Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2018
- 70 participants
- 1549 messages
[PATCH] wined3d: Add GL_ARB_shader_viewport_layer_array extension.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 1 +
dlls/wined3d/glsl_shader.c | 2 ++
dlls/wined3d/wined3d_gl.h | 1 +
3 files changed, 4 insertions(+)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 1d360d104bf8..1722438a5a10 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -113,6 +113,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
{"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT},
{"GL_ARB_shader_texture_image_samples", ARB_SHADER_TEXTURE_IMAGE_SAMPLES},
{"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD },
+ {"GL_ARB_shader_viewport_layer_array", ARB_SHADER_VIEWPORT_LAYER_ARRAY},
{"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 },
{"GL_ARB_shading_language_420pack", ARB_SHADING_LANGUAGE_420PACK },
{"GL_ARB_shading_language_packing", ARB_SHADING_LANGUAGE_PACKING },
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 52348084c388..0db7fdc038b0 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -8140,6 +8140,8 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
shader_addline(buffer, "#extension GL_ARB_draw_instanced : enable\n");
if (shader_glsl_use_explicit_attrib_location(gl_info))
shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
+ if (gl_info->supported[ARB_SHADER_VIEWPORT_LAYER_ARRAY])
+ shader_addline(buffer, "#extension GL_ARB_shader_viewport_layer_array : enable\n");
/* Base Declarations */
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 525c29803a50..06aa21c33fa6 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -93,6 +93,7 @@ enum wined3d_gl_extension
ARB_SAMPLER_OBJECTS,
ARB_SEAMLESS_CUBE_MAP,
ARB_SHADER_ATOMIC_COUNTERS,
+ ARB_SHADER_VIEWPORT_LAYER_ARRAY,
ARB_SHADER_BIT_ENCODING,
ARB_SHADER_IMAGE_LOAD_STORE,
ARB_SHADER_IMAGE_SIZE,
--
2.16.4
Sept. 25, 2018
[PATCH] testbot: Let VM scripts identify the last part of a patchset.
by Francois Gouget
For patchsets (and subsets thereof) the Engine calls GetPatchImpacts()
at least once with only the last part. This allows it to know exactly
what the last part modifies and thus what needs to be retested.
However the VM scripts only have the full patchset so they don't know
what the last part is. Thus they are forced to rerun every test touched
by the full patchset.
So the TestBot now adds a marker before the last part, allowing
GetPatchImpacts() to identify it. Note that it does not use '---' as
that marker may or may not be present depending on how the patch was
formatted for emailing (and can be ambiguous too).
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/PatchUtils.pm | 76 +++++++++++++++------
testbot/lib/WineTestBot/Patches.pm | 5 +-
testbot/lib/WineTestBot/PendingPatchSets.pm | 5 ++
3 files changed, 60 insertions(+), 26 deletions(-)
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index b7307e527..f03cc40bb 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -31,7 +31,8 @@ the Wine builds.
=cut
use Exporter 'import';
-our @EXPORT = qw(GetPatchImpacts UpdateWineData GetBuildTimeout);
+our @EXPORT = qw(GetPatchImpacts LastPartSeparator UpdateWineData
+ GetBuildTimeout);
use List::Util qw(min max);
@@ -150,6 +151,11 @@ my $IgnoredPathsRe = join('|',
'tools/winemaker/',
);
+sub LastPartSeparator()
+{
+ return "===== TestBot: Last patchset part =====\n";
+}
+
sub _CreateTestInfo($$$)
{
my ($Impacts, $Root, $Dir) = @_;
@@ -261,9 +267,9 @@ configure, whether it impacts the tests, etc.
=back
=cut
-sub GetPatchImpacts($;$)
+sub GetPatchImpacts($)
{
- my ($PatchFileName, $PastImpacts) = @_;
+ my ($PatchFileName) = @_;
my $fh;
return undef if (!open($fh, "<", $PatchFileName));
@@ -281,25 +287,7 @@ sub GetPatchImpacts($;$)
};
_LoadWineFiles();
- if ($PastImpacts)
- {
- # Update the list of Wine files so we correctly recognize patchset parts
- # that modify new Wine files.
- my $WineFiles = $PastImpacts->{WineFiles} || $_WineFiles;
- map { $Impacts->{WineFiles}->{$_} = 1 } keys %{$WineFiles};
- map { $Impacts->{WineFiles}->{$_} = 1 } keys %{$PastImpacts->{NewFiles}};
- map { delete $Impacts->{WineFiles}->{$_} } keys %{$PastImpacts->{DeletedFiles}};
-
- foreach my $PastInfo (values %{$PastImpacts->{Tests}})
- {
- foreach my $File (keys %{$PastInfo->{Files}})
- {
- _HandleFile($Impacts, "$PastInfo->{Path}/$File",
- $PastInfo->{Files}->{$File} eq "rm" ? "rm" : 0);
- }
- }
- }
-
+ my $PastImpacts;
my ($Path, $Change);
while (my $Line = <$fh>)
{
@@ -332,6 +320,50 @@ sub GetPatchImpacts($;$)
$Path = undef;
$Change = "";
}
+ elsif ($Line eq LastPartSeparator())
+ {
+ # All the diffs so far belongs to previous parts of this patchset.
+ # But:
+ # - Only the last part must be taken into account to determine if a
+ # rebuild and testing is needed.
+ # - Yet if a rebuild is needed the previous parts' patches will impact
+ # the scope of the rebuild so that information must be preserved.
+ # So save current impacts in $PastImpacts and reset the current state.
+ $PastImpacts = {};
+
+ # Build a copy of the Wine files list reflecting the current situation.
+ $Impacts->{WineFiles} = { %$_WineFiles } if (!$Impacts->{WineFiles});
+ map { $Impacts->{WineFiles}->{$_} = 1 } keys %{$Impacts->{NewFiles}};
+ map { delete $Impacts->{WineFiles}->{$_} } keys %{$Impacts->{DeletedFiles}};
+ $Impacts->{NewFiles} = {};
+ $Impacts->{DeletedFiles} = {};
+
+ # The modules impacted by previous parts will still need to be built,
+ # but only if the last part justifies a build. So make a backup.
+ $PastImpacts->{BuildModules} = $Impacts->{BuildModules};
+ $Impacts->{BuildModules} = {};
+
+ # Also backup the build-related fields.
+ foreach my $Field ("Autoconf", "MakeMakefiles",
+ "PatchedRoot", "PatchedModules", "PatchedTests")
+ {
+ $PastImpacts->{$Field} = $Impacts->{$Field};
+ $Impacts->{$Field} = undef;
+ }
+
+ # Reset the status of all test unit files to not modified.
+ foreach my $TestInfo (values %{$Impacts->{Tests}})
+ {
+ foreach my $File (keys %{$TestInfo->{Files}})
+ {
+ if ($TestInfo->{Files}->{$File} ne "rm")
+ {
+ $TestInfo->{Files}->{$File} = 0;
+ }
+ }
+ }
+ $Impacts->{ModuleUnitCount} = $Impacts->{TestUnitCount} = 0;
+ }
else
{
$Path = undef;
diff --git a/testbot/lib/WineTestBot/Patches.pm b/testbot/lib/WineTestBot/Patches.pm
index 038754365..469fedcdc 100644
--- a/testbot/lib/WineTestBot/Patches.pm
+++ b/testbot/lib/WineTestBot/Patches.pm
@@ -132,10 +132,7 @@ sub Submit($$$)
{
my ($self, $PatchFileName, $IsSet) = @_;
- my $PastImpacts;
- $PastImpacts = GetPatchImpacts($PatchFileName) if ($IsSet);
- my $Impacts = GetPatchImpacts("$DataDir/patches/" . $self->Id, $PastImpacts);
-
+ my $Impacts = GetPatchImpacts($PatchFileName);
if (!$Impacts->{PatchedRoot} and !$Impacts->{PatchedModules} and
!$Impacts->{PatchedTests})
{
diff --git a/testbot/lib/WineTestBot/PendingPatchSets.pm b/testbot/lib/WineTestBot/PendingPatchSets.pm
index 3ac8c5350..286b39314 100644
--- a/testbot/lib/WineTestBot/PendingPatchSets.pm
+++ b/testbot/lib/WineTestBot/PendingPatchSets.pm
@@ -42,6 +42,7 @@ use WineTestBot::WineTestBotObjects;
our @ISA = qw(WineTestBot::WineTestBotItem);
use WineTestBot::Config;
+use WineTestBot::PatchUtils;
use WineTestBot::Utils;
@@ -116,6 +117,10 @@ sub SubmitSubset($$$)
last;
}
+ if ($PartNo == $MaxPart and $PartNo > 1)
+ {
+ print $CombinedFile LastPartSeparator();
+ }
if (open(my $PartFile, "<" , "$DataDir/patches/" . $Part->Patch->Id))
{
print $CombinedFile $_ for (<$PartFile>);
--
2.19.0
Sept. 25, 2018
[PATCH] d2d1: Add ID2D1Effect stub.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/Makefile.in | 1 +
dlls/d2d1/d2d1_private.h | 8 ++
dlls/d2d1/device.c | 12 ++-
dlls/d2d1/effect.c | 215 +++++++++++++++++++++++++++++++++++++++
4 files changed, 235 insertions(+), 1 deletion(-)
create mode 100644 dlls/d2d1/effect.c
diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in
index 4bfe3b5953..413571338b 100644
--- a/dlls/d2d1/Makefile.in
+++ b/dlls/d2d1/Makefile.in
@@ -9,6 +9,7 @@ C_SRCS = \
brush.c \
dc_render_target.c \
device.c \
+ effect.c \
factory.c \
geometry.c \
hwnd_render_target.c \
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 2d3acd5997..f378722b5d 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -503,6 +503,14 @@ struct d2d_device
void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN;
+struct d2d_effect
+{
+ ID2D1Effect ID2D1Effect_iface;
+ LONG refcount;
+};
+
+void d2d_effect_init(struct d2d_effect *effect) DECLSPEC_HIDDEN;
+
static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
{
size_t new_capacity, max_capacity;
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index be8b7eab03..e2fa414c58 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -1858,9 +1858,19 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(
static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext *iface,
REFCLSID effect_id, ID2D1Effect **effect)
{
+ struct d2d_effect *object;
+
FIXME("iface %p, effect_id %s, effect %p stub!\n", iface, debugstr_guid(effect_id), effect);
- return E_NOTIMPL;
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ d2d_effect_init(object);
+
+ TRACE("Created effect %p.\n", object);
+ *effect = &object->ID2D1Effect_iface;
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection(
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c
new file mode 100644
index 0000000000..b13269330f
--- /dev/null
+++ b/dlls/d2d1/effect.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2018 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "d2d1_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d2d);
+
+static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface)
+{
+ return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Effect_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out)
+{
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ if (IsEqualGUID(iid, &IID_ID2D1Effect)
+ || IsEqualGUID(iid, &IID_ID2D1Properties)
+ || IsEqualGUID(iid, &IID_IUnknown))
+ {
+ ID2D1Effect_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE d2d_effect_AddRef(ID2D1Effect *iface)
+{
+ struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
+ ULONG refcount = InterlockedIncrement(&effect->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG STDMETHODCALLTYPE d2d_effect_Release(ID2D1Effect *iface)
+{
+ struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
+ ULONG refcount = InterlockedDecrement(&effect->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ heap_free(effect);
+
+ return refcount;
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyCount(ID2D1Effect *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+
+ return 0;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_GetPropertyName(ID2D1Effect *iface, UINT32 index,
+ WCHAR *name, UINT32 name_count)
+{
+ FIXME("iface %p, index %u, name %s, name_count %u stub!\n", iface, index, debugstr_wn(name, name_count), name_count);
+
+ return E_NOTIMPL;
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyNameLength(ID2D1Effect *iface, UINT32 index)
+{
+ FIXME("iface %p, index %u stub!\n", iface, index);
+
+ return 0;
+}
+
+static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_GetType(ID2D1Effect *iface, UINT32 index)
+{
+ FIXME("iface %p, index %u stub!\n", iface, index);
+
+ return 0;
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyIndex(ID2D1Effect *iface, const WCHAR *name)
+{
+ FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name));
+
+ return 0;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_SetValueByName(ID2D1Effect *iface, const WCHAR *name,
+ D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size)
+{
+ FIXME("iface %p, name %s, type %#x, value %p, value_size %u stub!\n", iface, debugstr_w(name),
+ type, value, value_size);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_SetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type,
+ const BYTE *value, UINT32 value_size)
+{
+ FIXME("iface %p, index %u, type %#x, value %p, value_size %u stub!\n", iface, index, type, value, value_size);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, const WCHAR *name,
+ D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size)
+{
+ FIXME("iface %p, name %s, type %#x, value %p, value_size %u stub!\n", iface, debugstr_w(name), type,
+ value, value_size);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type,
+ BYTE *value, UINT32 value_size)
+{
+ FIXME("iface %p, index %u, type %#x, value %p, value_size %u stub!\n", iface, index, type,
+ value, value_size);
+
+ return E_NOTIMPL;
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index)
+{
+ FIXME("iface %p, index %u stub!\n", iface, index);
+
+ return 0;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, ID2D1Properties **props)
+{
+ FIXME("iface %p, index %u, props %p stub!\n", iface, index, props);
+
+ return E_NOTIMPL;
+}
+
+static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image *input, BOOL invalidate)
+{
+ FIXME("iface %p, index %u, input %p, invalidate %d stub!\n", iface, index, input, invalidate);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count)
+{
+ FIXME("iface %p, count %u stub!\n", iface, count);
+
+ return E_NOTIMPL;
+}
+
+static void STDMETHODCALLTYPE d2d_effect_GetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image **input)
+{
+ FIXME("iface %p, index %u, input %p stub!\n", iface, index, input);
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_GetInputCount(ID2D1Effect *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+
+ return 0;
+}
+
+static void STDMETHODCALLTYPE d2d_effect_GetOutput(ID2D1Effect *iface, ID2D1Image **output)
+{
+ FIXME("iface %p, output %p stub!\n", iface, output);
+}
+
+static const ID2D1EffectVtbl d2d_effect_vtbl =
+{
+ d2d_effect_QueryInterface,
+ d2d_effect_AddRef,
+ d2d_effect_Release,
+ d2d_effect_GetPropertyCount,
+ d2d_effect_GetPropertyName,
+ d2d_effect_GetPropertyNameLength,
+ d2d_effect_GetType,
+ d2d_effect_GetPropertyIndex,
+ d2d_effect_SetValueByName,
+ d2d_effect_SetValue,
+ d2d_effect_GetValueByName,
+ d2d_effect_GetValue,
+ d2d_effect_GetValueSize,
+ d2d_effect_GetSubProperties,
+ d2d_effect_SetInput,
+ d2d_effect_SetInputCount,
+ d2d_effect_GetInput,
+ d2d_effect_GetInputCount,
+ d2d_effect_GetOutput,
+};
+
+void d2d_effect_init(struct d2d_effect *effect)
+{
+ effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl;
+ effect->refcount = 1;
+}
+
--
2.19.0
Sept. 25, 2018
[PATCH 5/5] wined3d: Derive allowed shader versions from the current feature level.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d11/shader.c | 27 ---------------------------
dlls/d3d8/shader.c | 2 --
dlls/d3d9/shader.c | 2 --
dlls/wined3d/shader.c | 37 ++++++++++++++++++++++++++++++-------
include/wine/wined3d.h | 1 -
5 files changed, 30 insertions(+), 39 deletions(-)
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c
index 759c5702746d..a1da9effc2b8 100644
--- a/dlls/d3d11/shader.c
+++ b/dlls/d3d11/shader.c
@@ -517,27 +517,6 @@ static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
d3d_vertex_shader_wined3d_object_destroyed,
};
-static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level)
-{
- switch (feature_level)
- {
- case D3D_FEATURE_LEVEL_11_1:
- case D3D_FEATURE_LEVEL_11_0:
- return 5;
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0:
- return 4;
- case D3D_FEATURE_LEVEL_9_3:
- return 3;
- case D3D_FEATURE_LEVEL_9_2:
- case D3D_FEATURE_LEVEL_9_1:
- return 2;
- default:
- ERR("Unexpected feature_level %#x.\n", feature_level);
- }
- return 0;
-}
-
static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
const void *byte_code, SIZE_T byte_code_length)
{
@@ -557,7 +536,6 @@ static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d
wined3d_mutex_unlock();
return hr;
}
- desc.max_version = d3d_sm_from_feature_level(device->feature_level);
hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
&d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader);
@@ -769,7 +747,6 @@ static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d
wined3d_mutex_unlock();
return hr;
}
- desc.max_version = d3d_sm_from_feature_level(device->feature_level);
hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
&d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader);
@@ -971,7 +948,6 @@ static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, stru
wined3d_mutex_unlock();
return hr;
}
- desc.max_version = d3d_sm_from_feature_level(device->feature_level);
hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
&d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader);
@@ -1477,7 +1453,6 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
WARN("Failed to extract shader, hr %#x.\n", hr);
return hr;
}
- desc.max_version = d3d_sm_from_feature_level(device->feature_level);
memset(&so_desc, 0, sizeof(so_desc));
if (so_entries)
@@ -1827,7 +1802,6 @@ static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d
wined3d_mutex_unlock();
return hr;
}
- desc.max_version = d3d_sm_from_feature_level(device->feature_level);
hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
&d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
@@ -2037,7 +2011,6 @@ static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, st
wined3d_mutex_unlock();
return hr;
}
- desc.max_version = d3d_sm_from_feature_level(device->feature_level);
hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
&d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader);
diff --git a/dlls/d3d8/shader.c b/dlls/d3d8/shader.c
index 8192b238ebd7..8a6881200e8b 100644
--- a/dlls/d3d8/shader.c
+++ b/dlls/d3d8/shader.c
@@ -121,7 +121,6 @@ HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_d
desc.input_signature.element_count = 0;
desc.output_signature.element_count = 0;
desc.patch_constant_signature.element_count = 0;
- desc.max_version = 1;
wined3d_mutex_lock();
hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
@@ -173,7 +172,6 @@ HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_dev
desc.input_signature.element_count = 0;
desc.output_signature.element_count = 0;
desc.patch_constant_signature.element_count = 0;
- desc.max_version = 1;
wined3d_mutex_lock();
hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
diff --git a/dlls/d3d9/shader.c b/dlls/d3d9/shader.c
index 9cb398388b91..5fc356c8e8af 100644
--- a/dlls/d3d9/shader.c
+++ b/dlls/d3d9/shader.c
@@ -148,7 +148,6 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *
desc.input_signature.element_count = 0;
desc.output_signature.element_count = 0;
desc.patch_constant_signature.element_count = 0;
- desc.max_version = 3;
wined3d_mutex_lock();
hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
@@ -302,7 +301,6 @@ HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *de
desc.input_signature.element_count = 0;
desc.output_signature.element_count = 0;
desc.patch_constant_signature.element_count = 0;
- desc.max_version = 3;
wined3d_mutex_lock();
hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 20d4f0773dd7..62ec97154141 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3321,8 +3321,8 @@ const struct wined3d_shader_backend_ops none_shader_backend =
shader_none_has_ffp_proj_control,
};
-static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_const_count,
- enum wined3d_shader_type type, unsigned int max_version)
+static HRESULT shader_set_function(struct wined3d_shader *shader,
+ unsigned int float_const_count, enum wined3d_shader_type type, unsigned int max_version)
{
const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
@@ -3351,12 +3351,12 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, DWORD float_co
if (reg_maps->shader_version.type != type)
{
- WARN("Wrong shader type %d.\n", reg_maps->shader_version.type);
+ WARN("Wrong shader type %#x.\n", reg_maps->shader_version.type);
return WINED3DERR_INVALIDCALL;
}
if (reg_maps->shader_version.major > max_version)
{
- WARN("Shader version %d not supported by this D3D API version.\n", reg_maps->shader_version.major);
+ WARN("Shader version %u not supported by this device.\n", reg_maps->shader_version.major);
return WINED3DERR_INVALIDCALL;
}
switch (type)
@@ -3636,17 +3636,40 @@ static HRESULT shader_signature_copy(struct wined3d_shader_signature *dst,
return WINED3D_OK;
}
+static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_level level)
+{
+ switch (level)
+ {
+ case WINED3D_FEATURE_LEVEL_11_1:
+ case WINED3D_FEATURE_LEVEL_11:
+ return 5;
+ case WINED3D_FEATURE_LEVEL_10_1:
+ case WINED3D_FEATURE_LEVEL_10:
+ return 4;
+ case WINED3D_FEATURE_LEVEL_9_SM3:
+ return 3;
+ case WINED3D_FEATURE_LEVEL_9_SM2:
+ case WINED3D_FEATURE_LEVEL_9_1:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
const struct wined3d_shader_desc *desc, DWORD float_const_count, enum wined3d_shader_type type,
void *parent, const struct wined3d_parent_ops *parent_ops)
{
+ unsigned int max_version;
size_t byte_code_size;
SIZE_T total;
HRESULT hr;
char *ptr;
- TRACE("byte_code %p, byte_code_size %#lx, format %#x, max_version %#x.\n",
- desc->byte_code, (long)desc->byte_code_size, desc->format, desc->max_version);
+ TRACE("byte_code %p, byte_code_size %#lx, format %#x.\n",
+ desc->byte_code, (long)desc->byte_code_size, desc->format);
+
+ max_version = shader_max_version_from_feature_level(device->feature_level);
if (!(shader->frontend = shader_select_frontend(desc->format)))
{
@@ -3732,7 +3755,7 @@ static HRESULT shader_init(struct wined3d_shader *shader, struct wined3d_device
memcpy(shader->function, desc->byte_code, byte_code_size);
shader->functionLength = byte_code_size;
- if (FAILED(hr = shader_set_function(shader, float_const_count, type, desc->max_version)))
+ if (FAILED(hr = shader_set_function(shader, float_const_count, type, max_version)))
{
WARN("Failed to set function, hr %#x.\n", hr);
shader_cleanup(shader);
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index ef89caf0633f..dc613fff2b2b 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2063,7 +2063,6 @@ struct wined3d_shader_desc
struct wined3d_shader_signature input_signature;
struct wined3d_shader_signature output_signature;
struct wined3d_shader_signature patch_constant_signature;
- unsigned int max_version;
};
struct wined3d_stream_output_element
--
2.16.4
Sept. 25, 2018
[PATCH 4/5] d3d11: Trace skipped DXBC chunks.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d11/d3d11_private.h | 2 --
dlls/d3d11/shader.c | 6 +-----
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 3049193ce284..e26554afabfc 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -47,10 +47,8 @@
#define TAG_OSG5 MAKE_TAG('O', 'S', 'G', '5')
#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N')
#define TAG_PCSG MAKE_TAG('P', 'C', 'S', 'G')
-#define TAG_RDEF MAKE_TAG('R', 'D', 'E', 'F')
#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R')
#define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X')
-#define TAG_STAT MAKE_TAG('S', 'T', 'A', 'T')
struct d3d_device;
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c
index c8d512f4d18f..759c5702746d 100644
--- a/dlls/d3d11/shader.c
+++ b/dlls/d3d11/shader.c
@@ -136,12 +136,8 @@ static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *
}
break;
- case TAG_RDEF:
- case TAG_STAT:
- break;
-
default:
- FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag, 4));
+ TRACE("Skipping chunk %s.\n", debugstr_an((const char *)&tag, 4));
break;
}
--
2.16.4
Sept. 25, 2018
[PATCH 3/5] wined3d: Cleanup fallback cards list.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/directx.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 925a5bc9eb8f..852b40584b7f 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -637,7 +637,6 @@ enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *
card_fallback_amd[] =
{
{WINED3D_FEATURE_LEVEL_5, CARD_AMD_RAGE_128PRO},
- {WINED3D_FEATURE_LEVEL_6, CARD_AMD_RAGE_128PRO},
{WINED3D_FEATURE_LEVEL_7, CARD_AMD_RADEON_7200},
{WINED3D_FEATURE_LEVEL_8, CARD_AMD_RADEON_8500},
{WINED3D_FEATURE_LEVEL_9_SM2, CARD_AMD_RADEON_9500},
@@ -649,10 +648,7 @@ enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *
card_fallback_intel[] =
{
{WINED3D_FEATURE_LEVEL_5, CARD_INTEL_845G},
- {WINED3D_FEATURE_LEVEL_6, CARD_INTEL_845G},
- {WINED3D_FEATURE_LEVEL_7, CARD_INTEL_845G},
{WINED3D_FEATURE_LEVEL_8, CARD_INTEL_915G},
- {WINED3D_FEATURE_LEVEL_9_SM2, CARD_INTEL_915G},
{WINED3D_FEATURE_LEVEL_9_SM3, CARD_INTEL_945G},
{WINED3D_FEATURE_LEVEL_10, CARD_INTEL_G45},
{WINED3D_FEATURE_LEVEL_11, CARD_INTEL_IVBD},
--
2.16.4
Sept. 25, 2018
[PATCH 2/5] dxgi: Merge dxgi_check_feature_level_support() into dxgi_adapter_CheckInterfaceSupport().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/adapter.c | 30 ++++++++++++++------------
dlls/dxgi/dxgi_private.h | 3 ---
dlls/dxgi/utils.c | 56 ------------------------------------------------
3 files changed, 16 insertions(+), 73 deletions(-)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c
index 1f81d7717e1b..4bc57a244d1f 100644
--- a/dlls/dxgi/adapter.c
+++ b/dlls/dxgi/adapter.c
@@ -209,9 +209,10 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IWineDXGIAdapter *iface, D
static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IWineDXGIAdapter *iface,
REFGUID guid, LARGE_INTEGER *umd_version)
{
- static const D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_10_0;
struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface);
struct wined3d_adapter_identifier adapter_id;
+ struct wined3d_caps caps;
+ struct wined3d *wined3d;
HRESULT hr;
TRACE("iface %p, guid %s, umd_version %p.\n", iface, debugstr_guid(guid), umd_version);
@@ -224,23 +225,24 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IWineDXGIAda
return DXGI_ERROR_UNSUPPORTED;
}
- if (!dxgi_check_feature_level_support(adapter->factory, adapter, &feature_level, 1))
- return DXGI_ERROR_UNSUPPORTED;
+ adapter_id.driver_size = 0;
+ adapter_id.description_size = 0;
+ adapter_id.device_name_size = 0;
- if (umd_version)
- {
- adapter_id.driver_size = 0;
- adapter_id.description_size = 0;
- adapter_id.device_name_size = 0;
+ wined3d_mutex_lock();
+ wined3d = adapter->factory->wined3d;
+ hr = wined3d_get_device_caps(wined3d, adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, &caps);
+ if (SUCCEEDED(hr))
+ hr = wined3d_get_adapter_identifier(wined3d, adapter->ordinal, 0, &adapter_id);
+ wined3d_mutex_unlock();
- wined3d_mutex_lock();
- hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id);
- wined3d_mutex_unlock();
- if (FAILED(hr))
- return hr;
+ if (FAILED(hr))
+ return hr;
+ if (caps.max_feature_level < WINED3D_FEATURE_LEVEL_10)
+ return DXGI_ERROR_UNSUPPORTED;
+ if (umd_version)
*umd_version = adapter_id.driver_version;
- }
return S_OK;
}
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 8c3e41a390bb..78f188634fcb 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -199,7 +199,4 @@ struct dxgi_surface
HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device,
IUnknown *outer, struct wined3d_texture *wined3d_texture) DECLSPEC_HIDDEN;
-D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter,
- const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) DECLSPEC_HIDDEN;
-
#endif /* __WINE_DXGI_PRIVATE_H */
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index ad8e2a23f2ae..73b37fda8b57 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -619,59 +619,3 @@ HRESULT dxgi_set_private_data_interface(struct wined3d_private_store *store,
return hr;
}
-
-static enum wined3d_feature_level wined3d_feature_level_from_d3d(D3D_FEATURE_LEVEL feature_level)
-{
- switch (feature_level)
- {
- case D3D_FEATURE_LEVEL_11_1:
- return WINED3D_FEATURE_LEVEL_11_1;
- case D3D_FEATURE_LEVEL_11_0:
- return WINED3D_FEATURE_LEVEL_11;
- case D3D_FEATURE_LEVEL_10_1:
- return WINED3D_FEATURE_LEVEL_10_1;
- case D3D_FEATURE_LEVEL_10_0:
- return WINED3D_FEATURE_LEVEL_10;
- case D3D_FEATURE_LEVEL_9_3:
- return WINED3D_FEATURE_LEVEL_9_SM3;
- case D3D_FEATURE_LEVEL_9_2:
- return WINED3D_FEATURE_LEVEL_9_SM2;
- case D3D_FEATURE_LEVEL_9_1:
- return WINED3D_FEATURE_LEVEL_9_1;
- default:
- FIXME("Unhandled feature level %#x.\n", feature_level);
- return 0;
- }
-}
-
-D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter,
- const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count)
-{
- enum wined3d_feature_level wined3d_feature_level;
- struct wined3d_caps caps;
- unsigned int i;
- HRESULT hr;
-
- wined3d_mutex_lock();
- hr = wined3d_get_device_caps(factory->wined3d, adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, &caps);
- wined3d_mutex_unlock();
-
- if (FAILED(hr))
- level_count = 0;
-
- for (i = 0; i < level_count; ++i)
- {
- wined3d_feature_level = wined3d_feature_level_from_d3d(feature_levels[i]);
- if (wined3d_feature_level && caps.max_feature_level >= wined3d_feature_level)
- {
- TRACE("Choosing supported feature level %s.\n",
- debug_feature_level(feature_levels[i]));
- return feature_levels[i];
- }
-
- TRACE("Feature level %s not supported, trying next fallback if available.\n",
- debug_feature_level(feature_levels[i]));
- }
-
- return 0;
-}
--
2.16.4
Sept. 25, 2018
[PATCH 1/5] dxgi: Simplify dxgi_adapter_GetDesc().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/adapter.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c
index b7d7a0a65aae..1f81d7717e1b 100644
--- a/dlls/dxgi/adapter.c
+++ b/dlls/dxgi/adapter.c
@@ -200,9 +200,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IWineDXGIAdapter *iface, D
if (!desc)
return E_INVALIDARG;
- if (FAILED(hr = dxgi_adapter_GetDesc1(iface, &desc1)))
- return hr;
- memcpy(desc, &desc1, sizeof(*desc));
+ if (SUCCEEDED(hr = dxgi_adapter_GetDesc1(iface, &desc1)))
+ memcpy(desc, &desc1, sizeof(*desc));
return hr;
}
--
2.16.4
Sept. 25, 2018
[PATCH 4/4] cmd: ftype failed to clear file associations
by Jason Edmeades
If a file association was set (e.g. ftype fred=xxx), ftype fred= needs to clear it,
but previously it failed to do so
---
Fixes a fixme from the tests and implements a test for the patch which adds
ShellExecute support for launching programs
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/cmd/builtins.c | 6 +++---
programs/cmd/tests/test_builtins.cmd | 9 +++++++++
programs/cmd/tests/test_builtins.cmd.exp | 5 ++++-
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 25b98813ba..879cb8dcb6 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -4939,11 +4939,11 @@ void WCMD_assoc (const WCHAR *args, BOOL assoc) {
/* If nothing after '=' then clear value - only valid for ASSOC */
if (*newValue == 0x00) {
- if (assoc) rc = RegDeleteKeyW(key, args);
- if (assoc && rc == ERROR_SUCCESS) {
+ rc = RegDeleteTreeW(key, args);
+ if (rc == ERROR_SUCCESS) {
WINE_TRACE("HKCR Key '%s' deleted\n", wine_dbgstr_w(args));
- } else if (assoc && rc != ERROR_FILE_NOT_FOUND) {
+ } else if (rc != ERROR_FILE_NOT_FOUND) {
WCMD_print_error();
errorlevel = 2;
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 79233d8d6f..0651056d1f 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -2398,6 +2398,12 @@ echo echo +++>> tmp.cmd
echo ftype footype>> tmp.cmd
cmd /c tmp.cmd
+echo --- testing association
+ftype footype=cmd.exe /c "echo '%%1'"
+echo dummy>test.foo
+test.foo
+del test.foo
+
echo --- resetting association
assoc .foo=
@@ -2429,6 +2435,9 @@ echo .foo=footype
echo footype=foo_opencmd
echo +++
echo footype=foo_opencmd
+echo --- testing association
+echo footype=cmd.exe /c "echo '%%1'"
+echo Skipped as not enough permissions
echo --- resetting association
echo original value
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 797a9cc8ae..52759f1b69 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -1430,8 +1430,11 @@ footype=foo_opencmd
footype=foo_opencmd
+++
footype=foo_opencmd
+--- testing association
+footype=cmd.exe /c "echo '%1'"
+'@drive@@path(a)foobar\test.foo'@or_broken(a)Skipped as not enough permissions
--- resetting association
-(a)todo_wine@original value(a)or_broken@buggyXP(a)or_broken@!WINE_FOO!
+original value(a)or_broken@buggyXP(a)or_broken@!WINE_FOO!
------------ Testing CALL ------------
--- external script
foo(a)space@
--
2.17.1
Sept. 25, 2018
[PATCH 3/4] cmd: Support for launching programs based on file association
by Jason Edmeades
cmd already handles exe, cmd, bat etc but if you run a file with another extension,
then use the associations set in the registry (for example via ftype / assoc) to
launch a program. This enables you to run test.txt and notepad to pop up, or
fred.msi for msiexec to be launched.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=18154
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=36646
---
Test for this added in the next patch, as ftype is broken at the moment,
and needs fixing first
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/cmd/wcmdmain.c | 140 +++++++++++++++++++++++++++++-----------
1 file changed, 104 insertions(+), 36 deletions(-)
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 5ef4a2bf34..348eec8ad9 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1143,8 +1143,10 @@ void WCMD_run_program (WCHAR *command, BOOL called)
/* 1. If extension supplied, see if that file exists */
if (extensionsupplied) {
- if (GetFileAttributesW(thisDir) != INVALID_FILE_ATTRIBUTES) {
+ DWORD attribs = GetFileAttributesW(thisDir);
+ if (attribs != INVALID_FILE_ATTRIBUTES && !(attribs&FILE_ATTRIBUTE_DIRECTORY)) {
found = TRUE;
+ WINE_TRACE("Found as file with extension as '%s'\n", wine_dbgstr_w(thisDir));
}
}
@@ -1175,6 +1177,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
}
if (GetFileAttributesW(thisDir) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found via search and pathext as '%s'\n", wine_dbgstr_w(thisDir));
found = TRUE;
thisExt = NULL;
}
@@ -1192,58 +1195,123 @@ void WCMD_run_program (WCHAR *command, BOOL called)
WCHAR *ext = strrchrW( thisDir, '.' );
static const WCHAR batExt[] = {'.','b','a','t','\0'};
static const WCHAR cmdExt[] = {'.','c','m','d','\0'};
+ static const WCHAR exeExt[] = {'.','e','x','e','\0'};
+ static const WCHAR comExt[] = {'.','c','o','m','\0'};
WINE_TRACE("Found as %s\n", wine_dbgstr_w(thisDir));
/* Special case BAT and CMD */
if (ext && (!strcmpiW(ext, batExt) || !strcmpiW(ext, cmdExt))) {
BOOL oldinteractive = interactive;
+ WINE_TRACE("Calling batch program\n");
interactive = FALSE;
WCMD_batch (thisDir, command, called, NULL, INVALID_HANDLE_VALUE);
interactive = oldinteractive;
+ WINE_TRACE("Back from call to batch program\n");
return;
- } else {
+ }
- /* thisDir contains the file to be launched, but with what?
- eg. a.exe will require a.exe to be launched, a.html may be iexplore */
- hinst = FindExecutableW (thisDir, NULL, temp);
- if ((INT_PTR)hinst < 32)
- console = 0;
- else
- console = SHGetFileInfoW(temp, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE);
-
- ZeroMemory (&st, sizeof(STARTUPINFOW));
- st.cb = sizeof(STARTUPINFOW);
- init_msvcrt_io_block(&st);
-
- /* Launch the process and if a CUI wait on it to complete
- Note: Launching internal wine processes cannot specify a full path to exe */
- status = CreateProcessW(thisDir,
- command, NULL, NULL, TRUE, 0, NULL, NULL, &st, &pe);
- heap_free(st.lpReserved2);
- if ((opt_c || opt_k) && !opt_s && !status
- && GetLastError()==ERROR_FILE_NOT_FOUND && command[0]=='\"') {
- /* strip first and last quote WCHARacters and try again */
- WCMD_strip_quotes(command);
- opt_s = TRUE;
- WCMD_run_program(command, called);
+ /* Calculate what program will be launched, and whether it is a
+ console application or not. Note the program may be different
+ from the parameter (eg running a .txt file will launch notepad.exe) */
+ hinst = FindExecutableW (thisDir, NULL, temp);
+ if ((INT_PTR)hinst < 32)
+ console = 0; /* Assume not console app by default */
+ else
+ console = SHGetFileInfoW(temp, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE);
+
+
+ /* If it is not a .com or .exe, try to launch through ShellExecuteExW
+ which takes into account the association for the extension. */
+ if (ext && (strcmpiW(ext, exeExt) && strcmpiW(ext, comExt))) {
+
+ SHELLEXECUTEINFOW shexw;
+ BOOL rc;
+ WCHAR *rawarg;
+
+ WCMD_parameter(command, 1, &rawarg, FALSE, TRUE);
+ WINE_TRACE("Launching via ShellExecuteEx\n");
+ memset(&shexw, 0x00, sizeof(shexw));
+ shexw.cbSize = sizeof(SHELLEXECUTEINFOW);
+ shexw.fMask = SEE_MASK_NO_CONSOLE | /* Run in same console as currently using */
+ SEE_MASK_NOCLOSEPROCESS; /* We need a process handle to possibly wait on */
+ shexw.lpFile = thisDir;
+ shexw.lpParameters = rawarg;
+ shexw.nShow = SW_SHOWNORMAL;
+
+ /* Try to launch the binary or its associated program */
+ rc = ShellExecuteExW(&shexw);
+
+ if (rc && (INT_PTR)shexw.hInstApp >= 32) {
+
+ WINE_TRACE("Successfully launched\n");
+
+ /* It worked... Always wait when non-interactive (cmd /c or in
+ batch program), or for console applications */
+ if (!interactive || (console && !HIWORD(console))) {
+ WINE_TRACE("Waiting for process to end\n");
+ WaitForSingleObject (shexw.hProcess, INFINITE);
+ }
+
+ GetExitCodeProcess (shexw.hProcess, &errorlevel);
+ if (errorlevel == STILL_ACTIVE) {
+ WINE_TRACE("Process still running, but returning anyway\n");
+ errorlevel = 0;
+ } else {
+ WINE_TRACE("Process ended, errorlevel %d\n", errorlevel);
+ }
+
+ CloseHandle(pe.hProcess);
return;
+
}
+ }
- if (!status)
- break;
+ /* If its a .exe or .com or the shellexecute failed due to no association,
+ CreateProcess directly */
+ ZeroMemory (&st, sizeof(STARTUPINFOW));
+ st.cb = sizeof(STARTUPINFOW);
+ init_msvcrt_io_block(&st);
+
+ /* Launch the process and if a CUI wait on it to complete
+ Note: Launching internal wine processes cannot specify a full path to exe */
+ WINE_TRACE("Launching via CreateProcess\n");
+ status = CreateProcessW(thisDir,
+ command, NULL, NULL, TRUE, 0, NULL, NULL, &st, &pe);
+ heap_free(st.lpReserved2);
+ if ((opt_c || opt_k) && !opt_s && !status
+ && GetLastError()==ERROR_FILE_NOT_FOUND && command[0]=='\"') {
+ /* strip first and last quote WCHARacters and try again */
+ WCMD_strip_quotes(command);
+ opt_s = TRUE;
+ WCMD_run_program(command, called);
+ return;
+ }
- /* Always wait when non-interactive (cmd /c or in batch program),
- or for console applications */
- if (!interactive || (console && !HIWORD(console)))
- WaitForSingleObject (pe.hProcess, INFINITE);
- GetExitCodeProcess (pe.hProcess, &errorlevel);
- if (errorlevel == STILL_ACTIVE) errorlevel = 0;
+ if (!status) {
+ WINE_TRACE("Failed to launch via CreateProcess, rc %d (%d)\n",
+ status, GetLastError());
+ break;
+ }
- CloseHandle(pe.hProcess);
- CloseHandle(pe.hThread);
- return;
+ /* Always wait when non-interactive (cmd /c or in batch program),
+ or for console applications */
+ if (!interactive || (console && !HIWORD(console))) {
+ WINE_TRACE("Waiting for process to end\n");
+ WaitForSingleObject (pe.hProcess, INFINITE);
}
+
+ GetExitCodeProcess (pe.hProcess, &errorlevel);
+ if (errorlevel == STILL_ACTIVE) {
+ WINE_TRACE("Process still running, but returning anyway\n");
+ errorlevel = 0;
+ } else {
+ WINE_TRACE("Process ended, errorlevel %d\n", errorlevel);
+ }
+
+ CloseHandle(pe.hProcess);
+ CloseHandle(pe.hThread);
+ return;
}
}
--
2.17.1
Sept. 25, 2018