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
June 2018
- 68 participants
- 1149 messages
[PATCH 2/2] testbot/build: Add proper command line options to Build.pl and Reconfig.pl.
by Francois Gouget
This makes it much easier to test the scripts directly on the VM.
This also makes it possible to test one aspect of the scripts without
having to go through the whole process. In particular the --no-rm
Reconfig.pl option speeds up testing by avoiding rebuilding from
scratch.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 175 +++++++++++++++++++++++-----------
testbot/bin/build/Reconfig.pl | 137 +++++++++++++++++++++++---
2 files changed, 241 insertions(+), 71 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 17ae74ff5..4df107005 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -43,12 +43,19 @@ sub BEGIN
}
$::BuildEnv = 1;
}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
use WineTestBot::Config;
use WineTestBot::PatchUtils;
use WineTestBot::Utils;
+#
+# Logging and error handling helpers
+#
+
sub InfoMsg(@)
{
print @_;
@@ -59,12 +66,16 @@ sub LogMsg(@)
print "Build: ", @_;
}
-sub FatalError(@)
+sub Error(@)
{
- print STDERR @_;
- exit 1;
+ print STDERR "$Name0:error: ", @_;
}
+
+#
+# Build helpers
+#
+
my $ncpus;
sub CountCPUs()
{
@@ -133,9 +144,11 @@ sub BuildNative()
return 1;
}
-sub BuildTestExecutables($$)
+sub BuildTestExecutables($$$)
{
- my ($Impacts, $Bits) = @_;
+ my ($Targets, $Impacts, $Bits) = @_;
+
+ return 1 if (!$Targets->{"exe$Bits"});
my (@BuildDirs, @TestExes);
foreach my $TestInfo (values %{$Impacts->{Tests}})
@@ -168,62 +181,113 @@ sub BuildTestExecutables($$)
return $Success;
}
+
+#
+# Setup and command line processing
+#
+
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
-my ($PatchFile, $BitIndicators);
-if (@ARGV == 2)
-{
- ($PatchFile, $BitIndicators) = @ARGV;
-}
-else
-{
- # FIXME Remove support for the legacy parameters
- my ($_PatchType, $_BaseName);
- ($PatchFile, $_PatchType, $_BaseName, $BitIndicators) = @ARGV;
-}
-if (! $PatchFile || !$BitIndicators)
-{
- FatalError "Usage: Build.pl <patchfile> <bits>\n";
-}
-
-# Verify parameters
-if (!IsValidFileName($PatchFile))
-{
- FatalError "The patch filename '$PatchFile' contains invalid characters\n";
-}
-$PatchFile = "$DataDir/staging/$PatchFile";
-if (!-r $PatchFile)
-{
- FatalError "Patch file '$PatchFile' is not readable\n";
-}
+my %AllTargets;
+map { $AllTargets{$_} = 1 } qw(exe32 exe64);
-my ($Run32, $Run64);
-if ($BitIndicators =~ m/^([\d,]+)$/)
+my ($Usage, $PatchFile, $TargetList);
+my $IgnoreNext = 0; # FIXME Backward compatibility
+while (@ARGV)
{
- foreach my $BitsValue (split /,/, $1)
+ my $Arg = shift @ARGV;
+ if ($Arg =~ /^patch(?:dlls|programs)$/)
{
- if ($BitsValue eq "32")
- {
- $Run32 = 1;
- }
- elsif ($BitsValue eq "64")
+ $IgnoreNext ||= 1; # Ignore this legacy parameter
+ }
+ elsif ($IgnoreNext == 1)
+ {
+ $IgnoreNext = 2; # Ignore this legacy parameter
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $PatchFile)
+ {
+ if (IsValidFileName($Arg))
{
- $Run64 = 1;
+ $PatchFile = "$DataDir/staging/$Arg";
+ if (!-r $PatchFile)
+ {
+ Error "patch file '$Arg' is not readable\n";
+ $Usage = 2;
+ }
}
else
{
- FatalError "Invalid number of bits $BitsValue\n";
+ Error "the patch filename '$Arg' contains invalid characters\n";
+ $Usage = 2;
+ last;
}
}
- if (!$Run32 && !$Run64)
+ elsif (!defined $TargetList)
{
- FatalError "Specify at least one of 32 or 64 bits\n";
+ $TargetList = $Arg;
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check and untaint parameters
+my $Targets;
+if (!defined $Usage)
+{
+ if (!defined $PatchFile)
+ {
+ Error "you must specify a patch to apply\n";
+ $Usage = 2;
+ }
+
+ $TargetList = join(",", keys %AllTargets) if (!defined $TargetList);
+ foreach my $Target (split /,/, $TargetList)
+ {
+ $Target = "exe$1" if ($Target =~ /^(32|64)$/);
+ if (!$AllTargets{$Target})
+ {
+ Error "invalid target name $Target\n";
+ $Usage = 2;
+ last;
+ }
+ $Targets->{$Target} = 1;
}
}
-else
+if (defined $Usage)
{
- FatalError "Invalid number of bits $BitIndicators\n";
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--help] PATCHFILE TARGETS\n";
+ print "\n";
+ print "Applies the specified patch and rebuilds the Wine test executables.\n";
+ print "\n";
+ print "Where:\n";
+ print " PATCHFILE Is the staging file containing the patch to build.\n";
+ print " TARGETS Is a comma-separated list of build targets. By default every\n";
+ print " target is run.\n";
+ print " - exe32: Rebuild the 32 bit Windows test executables.\n";
+ print " - exe64: Rebuild the 64 bit Windows test executables.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
}
if ($DataDir =~ /'/)
@@ -232,20 +296,19 @@ if ($DataDir =~ /'/)
exit(1);
}
-my $Impacts = ApplyPatch($PatchFile);
-exit(1) if (!$Impacts);
+
+#
+# Run the builds
+#
CountCPUs();
-if ($Impacts->{WineBuild} and !BuildNative())
-{
- exit(1);
-}
-if ($Run32 && !BuildTestExecutables($Impacts, 32))
-{
- exit(1);
-}
-if ($Run64 && !BuildTestExecutables($Impacts, 64))
+my $Impacts = ApplyPatch($PatchFile);
+
+if (!$Impacts or
+ ($Impacts->{WineBuild} and !BuildNative()) or
+ !BuildTestExecutables($Targets, $Impacts, 32) or
+ !BuildTestExecutables($Targets, $Impacts, 64))
{
exit(1);
}
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index 5ecbc2af3..450de0e83 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -38,12 +38,19 @@ sub BEGIN
unshift @INC, "$::RootDir/lib";
}
$::BuildEnv = 1;
- }
+}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
use WineTestBot::Config;
use WineTestBot::PatchUtils;
+#
+# Logging and error handling helpers
+#
+
sub InfoMsg(@)
{
print @_;
@@ -54,6 +61,16 @@ sub LogMsg(@)
print "Reconfig: ", @_;
}
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_;
+}
+
+
+#
+# Build helpers
+#
+
my $ncpus;
sub CountCPUs()
{
@@ -108,8 +125,11 @@ sub BuildTestLauncher()
return 1;
}
-sub GitPull()
+sub GitPull($)
{
+ my ($Targets) = @_;
+ return 1 if (!$Targets->{update});
+
InfoMsg "\nUpdating the Wine source\n";
system("cd '$DataDir/wine' && git pull");
if ($? != 0)
@@ -128,14 +148,17 @@ sub GitPull()
return 1;
}
-sub BuildNative()
+sub BuildNative($$)
{
+ my ($Targets, $NoRm) = @_;
+
+ return 1 if (!$Targets->{native});
mkdir "$DataDir/build-native" if (! -d "$DataDir/build-native");
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
system("cd '$DataDir/build-native' && set -x && ".
- "rm -rf * && ".
+ ($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus __tooldeps__");
@@ -148,17 +171,18 @@ sub BuildNative()
return 1;
}
-sub BuildCross($)
+sub BuildCross($$$)
{
- my ($Bits) = @_;
+ my ($Targets, $NoRm, $Bits) = @_;
- my $Host = ($Bits == 64 ? "x86_64-w64-mingw32" : "i686-w64-mingw32");
- mkdir "$DataDir/build-mingw$Bits" if (! -d "$DataDir/build-mingw$Bits");
+ return 1 if (!$Targets->{"exe$Bits"});
+ mkdir "$DataDir/build-mingw$Bits" if (!-d "$DataDir/build-mingw$Bits");
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
+ my $Host = ($Bits == 64 ? "x86_64-w64-mingw32" : "i686-w64-mingw32");
system("cd '$DataDir/build-mingw$Bits' && set -x && ".
- "rm -rf * && ".
+ ($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus buildtests");
if ($? != 0)
@@ -170,9 +194,87 @@ sub BuildCross($)
return 1;
}
+
+#
+# Setup and command line processing
+#
+
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
+my %AllTargets;
+map { $AllTargets{$_} = 1 } qw(update native exe32 exe64);
+
+my ($Usage, $TargetList, $NoRm);
+while (@ARGV)
+{
+ my $Arg = shift @ARGV;
+ if ($Arg eq "--no-rm")
+ {
+ $NoRm = 1;
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $TargetList)
+ {
+ $TargetList = $Arg;
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check and untaint parameters
+my $Targets;
+if (!defined $Usage)
+{
+ $TargetList = join(",", keys %AllTargets) if (!defined $TargetList);
+ foreach my $Target (split /,/, $TargetList)
+ {
+ if (!$AllTargets{$Target})
+ {
+ Error "invalid target name $Target\n";
+ $Usage = 2;
+ last;
+ }
+ $Targets->{$Target} = 1;
+ }
+}
+if (defined $Usage)
+{
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--no-rm] [--help] [TARGETS]\n";
+ print "\n";
+ print "Updates Wine to the latest version and recompiles it so the host is ready to build executables for the Windows tests.\n";
+ print "\n";
+ print "Where:\n";
+ print " TARGETS Is a comma-separated list of reconfiguration targets. By default\n";
+ print " every target is run.\n";
+ print " - update: Update Wine's source code.\n";
+ print " - native: Rebuild the native Wine tools.\n";
+ print " - exe32: Rebuild the 32 bit Windows test executables.\n";
+ print " - exe64: Rebuild the 64 bit Windows test executables.\n";
+ print " --no-rm Don't rebuild from scratch.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
+}
+
if ($DataDir =~ /'/)
{
LogMsg "The install path contains invalid characters\n";
@@ -184,14 +286,19 @@ if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
exit(1);
}
+
+#
+# Run the builds
+#
+
CountCPUs();
-if (!BuildTestAgentd() ||
- !BuildTestLauncher() ||
- !GitPull() ||
- !BuildNative() ||
- !BuildCross(32) ||
- !BuildCross(64))
+if (!BuildTestAgentd() or
+ !BuildTestLauncher() or
+ !GitPull($Targets) or
+ !BuildNative($Targets, $NoRm) or
+ !BuildCross($Targets, $NoRm, 32) or
+ !BuildCross($Targets, $NoRm, 64))
{
exit(1);
}
--
2.17.1
June 21, 2018
[PATCH 1/2] testbot/build: Quote the paths in the shell commands.
by Francois Gouget
Also check that $DataDir does not contain single quotes, thus ensuring
our simple quoting scheme works.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
A more absolutist approach would be to use ShQuote() everywhere which
would remove the single quote restriction. But that would compromise
readability. So this solution seems like a good compromise.
Also this is mostly cosmetic in the first place since the administrator
would presumably not put spaces, stars, dollar signs or single quotes in
the $DataDir path. Still I much prefer having proper quoting in my shell
scripts.
testbot/bin/build/Build.pl | 16 +++++++++++-----
testbot/bin/build/Reconfig.pl | 17 +++++++++++------
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index c23bb8780..17ae74ff5 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -82,7 +82,7 @@ sub ApplyPatch($)
my ($PatchFile) = @_;
InfoMsg "Applying patch\n";
- system("cd $DataDir/wine && set -x && ".
+ system("cd '$DataDir/wine' && set -x && ".
"git apply --verbose ". ShQuote($PatchFile) ." && ".
"git add -A");
if ($? != 0)
@@ -95,7 +95,7 @@ sub ApplyPatch($)
if ($Impacts->{Makefiles})
{
InfoMsg "\nRunning make_makefiles\n";
- system("cd $DataDir/wine && set -x && ./tools/make_makefiles");
+ system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
if ($? != 0)
{
LogMsg "make_makefiles failed\n";
@@ -106,7 +106,7 @@ sub ApplyPatch($)
if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
{
InfoMsg "\nRunning autoconf\n";
- system("cd $DataDir/wine && set -x && autoconf");
+ system("cd '$DataDir/wine' && set -x && autoconf");
if ($? != 0)
{
LogMsg "Autoconf failed\n";
@@ -122,7 +122,7 @@ sub BuildNative()
mkdir "$DataDir/build-native" if (! -d "$DataDir/build-native");
InfoMsg "\nRebuilding native tools\n";
- system("cd $DataDir/build-native && set -x && ".
+ system("cd '$DataDir/build-native' && set -x && ".
"time make -j$ncpus __tooldeps__");
if ($? != 0)
{
@@ -147,7 +147,7 @@ sub BuildTestExecutables($$)
}
InfoMsg "\nBuilding the $Bits-bit test executable(s)\n";
- system("cd $DataDir/build-mingw$Bits && set -x && ".
+ system("cd '$DataDir/build-mingw$Bits' && set -x && ".
"time make -j$ncpus ". join(" ", sort @BuildDirs));
if ($? != 0)
{
@@ -226,6 +226,12 @@ else
FatalError "Invalid number of bits $BitIndicators\n";
}
+if ($DataDir =~ /'/)
+{
+ LogMsg "The install path contains invalid characters\n";
+ exit(1);
+}
+
my $Impacts = ApplyPatch($PatchFile);
exit(1) if (!$Impacts);
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index 2da2f54a4..5ecbc2af3 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -73,7 +73,7 @@ sub BuildTestAgentd()
if (! -x "$BinDir/build/testagentd")
{
InfoMsg "\nBuilding the native testagentd\n";
- system("cd $::RootDir/src/testagentd && set -x && ".
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
"time make -j$ncpus build");
if ($? != 0)
{
@@ -83,7 +83,7 @@ sub BuildTestAgentd()
}
InfoMsg "\nRebuilding the Windows TestAgentd\n";
- system("cd $::RootDir/src/testagentd && set -x && ".
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
"time make -j$ncpus iso");
if ($? != 0)
{
@@ -97,7 +97,7 @@ sub BuildTestAgentd()
sub BuildTestLauncher()
{
InfoMsg "\nRebuilding TestLauncher\n";
- system("cd $::RootDir/src/TestLauncher && set -x && ".
+ system("cd '$::RootDir/src/TestLauncher' && set -x && ".
"time make -j$ncpus");
if ($? != 0)
{
@@ -111,7 +111,7 @@ sub BuildTestLauncher()
sub GitPull()
{
InfoMsg "\nUpdating the Wine source\n";
- system("cd $DataDir/wine && git pull");
+ system("cd '$DataDir/wine' && git pull");
if ($? != 0)
{
LogMsg "Git pull failed\n";
@@ -134,7 +134,7 @@ sub BuildNative()
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
- system("cd $DataDir/build-native && set -x && ".
+ system("cd '$DataDir/build-native' && set -x && ".
"rm -rf * && ".
"time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus __tooldeps__");
@@ -157,7 +157,7 @@ sub BuildCross($)
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
- system("cd $DataDir/build-mingw$Bits && set -x && ".
+ system("cd '$DataDir/build-mingw$Bits' && set -x && ".
"rm -rf * && ".
"time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus buildtests");
@@ -173,6 +173,11 @@ sub BuildCross($)
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
+if ($DataDir =~ /'/)
+{
+ LogMsg "The install path contains invalid characters\n";
+ exit(1);
+}
if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
{
LogMsg "Unable to create '$DataDir/staging': $!\n";
--
2.17.1
June 21, 2018
[PATCH 3/3] testbot/WineRunTask: Rename the Windows test reports.
by Francois Gouget
Keep 'log' for the task log messages (such as the compilation log) and
store the actual (WineTest) test report in '.report' files.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
A coming patch will put the output of the batch file in the log file
(after I have checked that the TestBot VMs have the version of
TestAgentd where redirections work correctly).
testbot/bin/WineRunTask.pl | 16 ++++++++--------
testbot/web/JobDetails.pl | 9 ++++++---
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 7f92b8858..3f5a3ee8d 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -195,7 +195,7 @@ my $OldUMask = umask(002);
my $TaskDir = $Task->CreateDir();
umask($OldUMask);
my $VM = $Task->VM;
-my $RptFileName = $VM->Name . ".rpt";
+my $RptFileName = $Step->FileType .".report";
my $Start = Time();
@@ -292,13 +292,13 @@ sub WrapUpAndExit($;$$$)
if ($Step->Type eq 'suite' and $Status eq 'completed' and !$TimedOut)
{
# Keep the old report if the new one is missing
- if (-f "$TaskDir/log" and !-z "$TaskDir/log")
+ if (-f "$TaskDir/$RptFileName" and !-z "$TaskDir/$RptFileName")
{
# Update the reference VM suite results for WineSendLog.pl
my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name, "_",
$Step->FileType eq "exe64" ? "64" : "32");
unlink("$LatestBaseName.log");
- link("$TaskDir/log", "$LatestBaseName.log");
+ link("$TaskDir/$RptFileName", "$LatestBaseName.log");
unlink("$LatestBaseName.err");
if (-f "$TaskDir/err" and !-z "$TaskDir/err")
{
@@ -518,11 +518,11 @@ if (!defined $TA->Wait($Pid, $Timeout, $Keepalive))
}
my $TimedOut;
-Debug(Elapsed($Start), " Retrieving the report file to 'log'\n");
-if ($TA->GetFile($RptFileName, "$TaskDir/log"))
+Debug(Elapsed($Start), " Retrieving the report file to '$RptFileName'\n");
+if ($TA->GetFile($RptFileName, "$TaskDir/$RptFileName"))
{
- chmod 0664, "$TaskDir/log";
- if (open(my $LogFile, "<", "$TaskDir/log"))
+ chmod 0664, "$TaskDir/$RptFileName";
+ if (open(my $LogFile, "<", "$TaskDir/$RptFileName"))
{
# There is more than one test unit when running the full test suite so keep
# track of the current one. Note that for the TestBot we don't count or
@@ -788,7 +788,7 @@ if ($TA->GetFile($RptFileName, "$TaskDir/log"))
else
{
$NewStatus = 'boterror';
- Error "Unable to open 'log' for reading: $!\n";
+ Error "Unable to open '$RptFileName' for reading: $!\n";
LogTaskError("Unable to open the log file for reading: $!\n");
}
}
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 3add52b4c..a1a846ff9 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -280,9 +280,12 @@ sub GetHtmlLine($$$)
return (undef, $Line);
}
+my @MILogFiles = qw(exe32.report exe64.report log log.old);
my %MILogLabels = (
- "log" => "task log",
- "log.old" => "old logs",
+ "exe32.report" => "32 bit Windows report",
+ "exe64.report" => "64 bit Windows report",
+ "log" => "task log",
+ "log.old" => "old logs",
);
sub InitMoreInfo($)
@@ -298,7 +301,7 @@ sub InitMoreInfo($)
my $Value = $self->GetParam("f$Key");
my $TaskDir = $StepTask->GetTaskDir();
- foreach my $Log ("log", "log.old")
+ foreach my $Log (@MILogFiles)
{
if (!-f "$TaskDir/$Log" or -z "$TaskDir/$Log")
{
--
2.17.1
June 21, 2018
[PATCH 2/3] testbot/WineRunTask: Preserve the old WineTest report in case of timeout.
by Francois Gouget
If the task timed out the new report is likely quite incomplete and thus
would be a poor substitute for the existing reference WineTest report.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index ed190348b..7f92b8858 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -289,7 +289,7 @@ sub WrapUpAndExit($;$$$)
$VM->Save();
}
- if ($Status eq 'completed' and $Step->Type eq 'suite')
+ if ($Step->Type eq 'suite' and $Status eq 'completed' and !$TimedOut)
{
# Keep the old report if the new one is missing
if (-f "$TaskDir/log" and !-z "$TaskDir/log")
--
2.17.1
June 21, 2018
[PATCH 1/3] testbot/WineRunTask: Keep the old reference report if the new one is missing.
by Francois Gouget
The WineTest results usually don't change too much from one run to the
next so it's better to have a slightly out of date report than nothing
at all.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index c4ca578e2..ed190348b 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -291,13 +291,20 @@ sub WrapUpAndExit($;$$$)
if ($Status eq 'completed' and $Step->Type eq 'suite')
{
- # Update the reference VM suite results for WineSendLog.pl
- my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name, "_",
- $Step->FileType eq "exe64" ? "64" : "32");
- unlink("$LatestBaseName.log");
- link("$TaskDir/log", "$LatestBaseName.log") if (-f "$TaskDir/log");
- unlink("$LatestBaseName.err");
- link("$TaskDir/err", "$LatestBaseName.err") if (-f "$TaskDir/err");
+ # Keep the old report if the new one is missing
+ if (-f "$TaskDir/log" and !-z "$TaskDir/log")
+ {
+ # Update the reference VM suite results for WineSendLog.pl
+ my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name, "_",
+ $Step->FileType eq "exe64" ? "64" : "32");
+ unlink("$LatestBaseName.log");
+ link("$TaskDir/log", "$LatestBaseName.log");
+ unlink("$LatestBaseName.err");
+ if (-f "$TaskDir/err" and !-z "$TaskDir/err")
+ {
+ link("$TaskDir/err", "$LatestBaseName.err");
+ }
+ }
}
my $Result = $VM->Name .": ". $VM->Status ." Status: $Status Failures: ". (defined $TestFailures ? $TestFailures : "unset");
--
2.17.1
June 21, 2018
[PATCH] testbot/WineRun*: Don't duplicate errors and factorize the log parsing.
by Francois Gouget
Move the task log parsing functions to LogUtils.pm so the WineRun*.pl
scripts can share them.
Also stop copying the 'Build: *' result lines from the log to the err
file. It's up to the GUI to present all the relevant lines when only
showing the log summary (which it does now).
Finally, there is nothing for the script to do if the patch fails to
apply. So even if we did not get the full log or the task timed out
somehow, the status of the task should be 'badpatch' and the other
errors don't matter.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 49 ++++++++----------
testbot/bin/WineRunReconfig.pl | 49 ++++++------------
testbot/lib/WineTestBot/LogUtils.pm | 77 +++++++++++++++++++++++++++++
3 files changed, 111 insertions(+), 64 deletions(-)
create mode 100644 testbot/lib/WineTestBot/LogUtils.pm
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index 1bc6cffbc..60af32c73 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -46,6 +46,7 @@ use WineTestBot::Jobs;
use WineTestBot::PatchUtils;
use WineTestBot::VMs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::Engine::Notify;
@@ -391,39 +392,29 @@ if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
Debug(Elapsed($Start), " Retrieving 'Build.log'\n");
if ($TA->GetFile("Build.log", "$TaskDir/log"))
{
- if (open(my $LogFile, "<", "$TaskDir/log"))
+ my $Result = ParseTaskLog("$TaskDir/log", "Build");
+ if ($Result eq "ok")
{
- # Collect and analyze the 'Build:' status line(s)
- $ErrMessage ||= "";
- foreach my $Line (<$LogFile>)
- {
- chomp($Line);
- next if ($Line !~ /^Build: (.*)$/);
- if ($1 eq "ok")
- {
- # We must have gotten the full log and the build did succeed.
- # So forget any prior error.
- $NewStatus = "completed";
- $TAError = $ErrMessage = undef;
- }
- else
- {
- $NewStatus = ($1 eq "Patch failed to apply") ? "badpatch" : "badbuild";
- # Collect all the build errors (32 bit, 64 bit, etc)
- $ErrMessage .= "$1\n";
- }
- }
- close($LogFile);
-
- if (!defined $NewStatus)
- {
- $NewStatus = "badbuild";
- $ErrMessage = "Missing build status line\n";
- }
+ # We must have gotten the full log and the build did succeed.
+ # So forget any prior error.
+ $NewStatus = "completed";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result eq "badpatch")
+ {
+ # This too is conclusive enough to ignore other errors.
+ $NewStatus = "badpatch";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result =~ s/^nolog://)
+ {
+ FatalError("$Result\n", "retry");
}
else
{
- FatalError("Unable to open the build log for reading: $!\n", "retry");
+ # If the result line is missing we probably already have an error message
+ # that explains why.
+ $NewStatus = "badbuild";
}
}
elsif (!defined $TAError)
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index d04b78061..2950799d5 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -45,6 +45,7 @@ use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::VMs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::Engine::Notify;
@@ -373,45 +374,23 @@ if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
Debug(Elapsed($Start), " Retrieving 'Reconfig.log'\n");
if ($TA->GetFile("Reconfig.log", "$TaskDir/log"))
{
- if (open(my $LogFile, "<", "$TaskDir/log"))
+ my $Result = ParseTaskLog("$TaskDir/log", "Reconfig");
+ if ($Result eq "ok")
{
- # Collect and analyze the 'Reconfig:' status line(s).
- my $LogErrors;
- foreach my $Line (<$LogFile>)
- {
- chomp($Line);
- next if ($Line !~ /^Reconfig: (.*)$/);
- # Add the error message or an empty string for 'ok'
- $LogErrors = ($LogErrors || "") . ($1 ne "ok" ? "$1\n" : "");
- }
- close($LogFile);
-
- if (!defined $LogErrors)
- {
- if (!defined $ErrMessage)
- {
- $NewStatus = "badbuild";
- $ErrMessage = "Missing reconfig status line\n";
- }
- # otherwise $ErrMessage probably already explains why the reconfig
- # status line is missing
- }
- elsif ($LogErrors eq "")
- {
- # We must have gotten the full log and the build did succeed.
- # So forget any prior error.
- $NewStatus = "completed";
- $TAError = $ErrMessage = undef;
- }
- else
- {
- $NewStatus = "badbuild";
- $ErrMessage = $LogErrors . ($ErrMessage || "");
- }
+ # We must have gotten the full log and the build did succeed.
+ # So forget any prior error.
+ $NewStatus = "completed";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result =~ s/^nolog://)
+ {
+ FatalError("$Result\n", "retry");
}
else
{
- FatalError("Unable to open the build log for reading: $!\n");
+ # We should not have badpatch errors and if the result line is missing we
+ # probably already have an error message that explains why.
+ $NewStatus = "badbuild";
}
}
elsif (!defined $TAError)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
new file mode 100644
index 000000000..3e40fbc35
--- /dev/null
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -0,0 +1,77 @@
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# Copyright 2018 Francois Gouget
+#
+# 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
+
+use strict;
+
+package WineTestBot::LogUtils;
+
+=head1 NAME
+
+WineTestBot::LogUtils - Provides functions to parse task logs
+
+=cut
+
+
+use Exporter 'import';
+our @EXPORT = qw(ParseTaskLog);
+
+
+#
+# Task log parser
+#
+
+=pod
+=over 12
+
+=item C<ParseTaskLog()>
+
+Returns ok if the task was successful and an error code otherwise.
+
+=back
+=cut
+
+sub ParseTaskLog($$)
+{
+ my ($FileName, $ResultPrefix) = @_;
+
+ if (open(my $LogFile, "<", $FileName))
+ {
+ my $Result;
+ foreach my $Line (<$LogFile>)
+ {
+ chomp $Line;
+ if ($Line =~ /^$ResultPrefix: ok$/)
+ {
+ $Result ||= "ok";
+ }
+ elsif ($Line =~ /^$ResultPrefix: Patch failed to apply$/)
+ {
+ $Result = "badpatch";
+ last; # Should be the last and most specific message
+ }
+ elsif ($Line =~ /^$ResultPrefix: /)
+ {
+ $Result = "failed";
+ }
+ }
+ close($LogFile);
+ return $Result || "missing";
+ }
+ return "nolog:Unable to open the task log for reading: $!";
+}
+
+1;
--
2.17.1
June 21, 2018
[PATCH] testbot: VMs::FilterHypervisors() is not used anymore so remove it.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/VMs.pm | 7 -------
1 file changed, 7 deletions(-)
diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm
index a29eebbba..2f494cb81 100644
--- a/testbot/lib/WineTestBot/VMs.pm
+++ b/testbot/lib/WineTestBot/VMs.pm
@@ -730,11 +730,4 @@ sub FilterEnabledStatus($)
$self->AddFilter("Status", ["dirty", "reverting", "sleeping", "idle", "running", "off", "offline"]);
}
-sub FilterHypervisors($$)
-{
- my ($self, $Hypervisors) = @_;
-
- $self->AddFilter("VirtURI", $Hypervisors);
-}
-
1;
--
2.17.1
June 21, 2018
[PATCH] testbot/web: Detect and highlight some more Git errors.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 8cc354e84..410d18691 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -253,9 +253,12 @@ sub GetHtmlLine($$$)
$Line =~ / done \(258\)/ or
$Line =~ /: unhandled exception [0-9a-fA-F]{8} at / or
$Line =~ /^Unhandled exception: / or
+ # Git errors
+ $Line =~ /^CONFLICT / or
+ $Line =~ /^error: patch failed:/ or
+ $Line =~ /^error: corrupt patch / or
# Build errors
$Line =~ /: error: / or
- $Line =~ /^error: patch failed:/ or
$Line =~ /^Makefile:[0-9]+: recipe for target .* failed$/ or
$Line =~ /^(?:Build|Reconfig|Task): (?!ok)/ or
# Typical perl errors
--
2.17.1
June 21, 2018
[PATCH 2/2] testbot/web: Prettify the log / error separator.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 7 ++++++-
testbot/web/WineTestBot.css | 14 ++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 1536e87cd..8cc354e84 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -495,7 +495,12 @@ sub GenerateBody($)
chomp $Line;
if ($ErrFirst)
{
- print "<hr>\n" if (!$LogFirst);
+ if (!$LogFirst)
+ {
+ print "<div class='HrTitle'>".
+ ($ErrName eq "err" ? "Other errors" : "Old errors") .
+ "<div class='HrLine'></div></div>\n";
+ }
print "<pre><code>";
$ErrFirst = 0;
}
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index 28ac1b1c2..593c38f44 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -317,6 +317,20 @@ h2
padding-bottom: 0.1em;
}
+.HrTitle {
+ margin-top: 0.5em;
+ display: flex;
+ align-items: center;
+ color: #a50d0d;
+}
+
+.HrLine {
+ border-top: 1px solid grey;
+ flex-grow: 1;
+ margin: 0 10px;
+ border-color: #a50d0d;
+}
+
details
{
font-style: italic;
--
2.17.1
June 21, 2018
[PATCH 1/2] testbot/web: Better present the logs and task errors.
by Francois Gouget
Add a horizontal ruler so the log / test report is always clearly
separated from the task error messages.
Avoid duplicating the code that shows the task errors.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 152 +++++++++++++++++---------------------
1 file changed, 67 insertions(+), 85 deletions(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 3add52b4c..1536e87cd 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -408,127 +408,109 @@ sub GenerateBody($)
my $LogName = $MoreInfo->{Full} || $MoreInfo->{Logs}->[0] || "log";
my $ErrName = $LogName eq "log.old" ? "err.old" : "err";
- if (open LOGFILE, "<", "$TaskDir/$LogName")
+ my ($EmptyDiag, $LogFirst);
+ if (open(my $LogFile, "<", "$TaskDir/$LogName"))
{
- my $HasLogEntries = !1;
- my $First = 1;
+ my $HasLogEntries;
my $CurrentDll = "";
my $PrintedDll = "";
- my $Line;
- while (defined($Line = <LOGFILE>))
+ $LogFirst = 1;
+ foreach my $Line (<$LogFile>)
{
$HasLogEntries = 1;
- chomp($Line);
+ chomp $Line;
if ($Line =~ m/^([^:]+):[^ ]+ start [^ ]+ -\s*$/)
{
$CurrentDll = $1;
}
my ($Highlight, $Plain) = $self->GetHtmlLine($MoreInfo->{Full}, $Line);
- if ($MoreInfo->{Full} || defined $Highlight)
+ next if (!$MoreInfo->{Full} and !defined $Highlight);
+
+ if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
+ {
+ print "</code></pre>" if (!$LogFirst);
+ print "<div class='LogDllName'>$CurrentDll:</div><pre><code>";
+ $PrintedDll = $CurrentDll;
+ $LogFirst = 0;
+ }
+ elsif ($LogFirst)
+ {
+ print "<pre><code>";
+ $LogFirst = 0;
+ }
+ if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
+ {
+ my $Unit = $1 ne "" ? "$1: " : "";
+ print "${Unit}Timeout\n";
+ }
+ else
{
- if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
- {
- if ($First)
- {
- $First = !1;
- }
- else
- {
- print "</code></pre>";
- }
- print "<div class='LogDllName'>$CurrentDll:</div><pre><code>";
- $PrintedDll = $CurrentDll;
- }
- elsif ($First)
- {
- print "<pre><code>";
- $First = !1;
- }
- if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
- {
- my $Unit = $1 ne "" ? "$1: " : "";
- print "${Unit}Timeout\n";
- }
- else
- {
- print(($Highlight || $Plain), "\n");
- }
+ print(($Highlight || $Plain), "\n");
}
}
- close LOGFILE;
+ close($LogFile);
- if (open ERRFILE, "<", "$TaskDir/$ErrName")
+ if (!$LogFirst)
{
- $CurrentDll = "*err*";
- while (defined($Line = <ERRFILE>))
+ print "</code></pre>\n";
+ }
+ elsif ($HasLogEntries)
+ {
+ # Here we know we did not show the full log since it was not empty,
+ # and yet we did not show anything to the user. But don't claim there
+ # is no failure if the error log is not empty.
+ if (-z "$TaskDir/$ErrName")
{
- $HasLogEntries = 1;
- chomp($Line);
- if ($PrintedDll ne $CurrentDll)
- {
- if ($First)
- {
- $First = !1;
- }
- else
- {
- print "</code></pre>\n";
- }
- print "<br><pre><code>";
- $PrintedDll = $CurrentDll;
- }
- print $self->escapeHTML($Line), "\n";
+ print "No ". ($StepTask->Type eq "single" ||
+ $StepTask->Type eq "suite" ? "test" : "build") .
+ " failures found";
+ $LogFirst = 0;
}
- close ERRFILE;
}
-
- if (! $First)
+ elsif ($StepTask->Status eq "canceled")
{
- print "</code></pre>\n";
+ $EmptyDiag = "<p>No log, task was canceled</p>\n";
+ }
+ elsif ($StepTask->Status eq "skipped")
+ {
+ $EmptyDiag = "<p>No log, task skipped</p>\n";
}
else
{
- print $HasLogEntries ? "No " .
- ($StepTask->Type eq "single" ||
- $StepTask->Type eq "suite" ? "test" : "build") .
- " failures found" : "Empty log";
+ print "Empty log";
+ $LogFirst = 0;
}
}
- elsif (open ERRFILE, "<", "$TaskDir/$ErrName")
+ else
+ {
+ print "No log". ($StepTask->Status =~ /^(?:queued|running)$/ ? " yet" : "");
+ $LogFirst = 0;
+ }
+
+ if (open(my $ErrFile, "<", "$TaskDir/$ErrName"))
{
- my $HasErrEntries = !1;
- my $Line;
- while (defined($Line = <ERRFILE>))
+ my $ErrFirst = 1;
+ foreach my $Line (<$ErrFile>)
{
- chomp($Line);
- if (! $HasErrEntries)
+ chomp $Line;
+ if ($ErrFirst)
{
+ print "<hr>\n" if (!$LogFirst);
print "<pre><code>";
- $HasErrEntries = 1;
+ $ErrFirst = 0;
}
print $self->escapeHTML($Line), "\n";
}
- if ($HasErrEntries)
+ close($ErrFile);
+
+ if (!$ErrFirst)
{
print "</code></pre>\n";
}
- else
+ elsif (defined $EmptyDiag)
{
- print "Empty log";
+ print $EmptyDiag;
}
- close ERRFILE;
- }
- elsif ($StepTask->Status eq "canceled")
- {
- print "<p>No log, task was canceled</p>\n";
- }
- elsif ($StepTask->Status eq "skipped")
- {
- print "<p>No log, task skipped</p>\n";
- }
- else
- {
- print "<p>No log available yet</p>\n";
}
}
print "</div>\n";
--
2.17.1
June 21, 2018
Re: [PATCH 2/2] msvcrt/tests: Use the available ARRAY_SIZE() macro
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 21, 2018
Re: [PATCH 1/2] msvcrt: Rename a macro to ARRAY_SIZE()
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 21, 2018
Re: [PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Alex Henrie
On Wed, Jun 20, 2018 at 11:59 PM Marvin <testbot(a)winehq.org> wrote:
>
> Hi,
>
> While running your changed tests on Windows, I think I found new failures.
> Being a bot and all I'm not very good at pattern recognition, so I might be
> wrong, but could you please double-check?
> Full results can be found at
> https://testbot.winehq.org/JobDetails.pl?Key=39269
>
> Your paranoid android.
>
>
> === wxppro (32 bit info) ===
> The task timed out
This is an intermittent failure which could not have been caused by
this patch's minor changes to the tests:
https://testbot.winehq.org/JobDetails.pl?Key=39279
-Alex
June 21, 2018
Re: [PATCH 1/2] iphlpapi: Use a standalone buffer in IcmpSendEcho().
by Huw Davies
On Thu, Jun 21, 2018 at 05:51:13PM +0800, Zhiyi Zhang wrote:
>
>
> On Thu 6 21 17:35, Huw Davies wrote:
> > On Fri, Jun 15, 2018 at 12:23:23PM +0800, Zhiyi Zhang wrote:
> >> Fix https://bugs.winehq.org/show_bug.cgi?id=43252
> >>
> >> The old implementation uses user provided buffer to receive
> >> packet data, which is alway not enough, causing data corruptions
> >> or incorrectly timeout.
> >>
> >> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
> >> ---
> >> dlls/iphlpapi/icmp.c | 38 +++++++++++++++++++++++++++-------
> >> dlls/iphlpapi/tests/iphlpapi.c | 21 +++++++++++++++----
> >> 2 files changed, 47 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
> >> index ebc2f2b65c..7c91443598 100644
> >> --- a/dlls/iphlpapi/icmp.c
> >> +++ b/dlls/iphlpapi/icmp.c
> >> @@ -113,6 +113,9 @@ typedef struct {
> >> #define IP_OPTS_DEFAULT 1
> >> #define IP_OPTS_CUSTOM 2
> >>
> >> +#define MAXIPLEN 60
> >> +#define MAXICMPLEN 76
> >
> > Out of interest, how did you get to 76?
> >
>
> That was copied from https://github.com/iputils/iputils/blob/master/ping.c#L76
I guess it's for errors: 8 for the icmp header, 60 for the
original ip header, then 8 for the original icmp header. We probably
don't need all of that, but it doesn't hurt.
Huw.
June 21, 2018
Re: [PATCH 1/2] iphlpapi: Use a standalone buffer in IcmpSendEcho().
by Zhiyi Zhang
On Thu 6 21 17:35, Huw Davies wrote:
> On Fri, Jun 15, 2018 at 12:23:23PM +0800, Zhiyi Zhang wrote:
>> Fix https://bugs.winehq.org/show_bug.cgi?id=43252
>>
>> The old implementation uses user provided buffer to receive
>> packet data, which is alway not enough, causing data corruptions
>> or incorrectly timeout.
>>
>> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
>> ---
>> dlls/iphlpapi/icmp.c | 38 +++++++++++++++++++++++++++-------
>> dlls/iphlpapi/tests/iphlpapi.c | 21 +++++++++++++++----
>> 2 files changed, 47 insertions(+), 12 deletions(-)
>>
>> diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
>> index ebc2f2b65c..7c91443598 100644
>> --- a/dlls/iphlpapi/icmp.c
>> +++ b/dlls/iphlpapi/icmp.c
>> @@ -113,6 +113,9 @@ typedef struct {
>> #define IP_OPTS_DEFAULT 1
>> #define IP_OPTS_CUSTOM 2
>>
>> +#define MAXIPLEN 60
>> +#define MAXICMPLEN 76
>
> Out of interest, how did you get to 76?
>
That was copied from https://github.com/iputils/iputils/blob/master/ping.c#L76
>> +
>> /* The sequence number is unique process wide, so that all threads
>> * have a distinct sequence number.
>> */
>> @@ -270,13 +273,14 @@ DWORD WINAPI IcmpSendEcho(
>> icmp_t* icp=(icmp_t*)IcmpHandle;
>> unsigned char* reqbuf;
>> int reqsize;
>> + unsigned char* repbuf;
>> + int repsize;
>>
>> struct icmp_echo_reply* ier;
>> struct ip* ip_header;
>> struct icmp* icmp_header;
>> char* endbuf;
>> int ip_header_len;
>> - int maxlen;
>> struct pollfd fdr;
>> DWORD send_time,recv_time;
>> struct sockaddr_in addr;
>> @@ -312,6 +316,16 @@ DWORD WINAPI IcmpSendEcho(
>> return 0;
>> }
>>
>> + /* max ip header + max icmp header and error data + reply size(max 65535 on Windows) */
>> + /* FIXME: request size of 65535 is not supported yet because max buffer size of raw socket on linux is 32767 */
>> + repsize=MAXIPLEN+MAXICMPLEN+(ReplySize&0xFFFF);
>> + repbuf=HeapAlloc(GetProcessHeap(), 0, repsize);
>> + if (reqbuf==NULL) {
>
> This should be repbuf.
>
>> + HeapFree(GetProcessHeap(), 0, reqbuf);
>> + SetLastError(ERROR_OUTOFMEMORY);
>> + return 0;
>> + }
>> +
>> icmp_header=(struct icmp*)reqbuf;
>> icmp_header->icmp_type=ICMP_ECHO;
>> icmp_header->icmp_code=0;
>> @@ -367,9 +381,7 @@ DWORD WINAPI IcmpSendEcho(
>> fdr.events = POLLIN;
>> addrlen=sizeof(addr);
>> ier=ReplyBuffer;
>> - ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY));
>> endbuf=(char *) ReplyBuffer+ReplySize;
>> - maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY);
>>
>> /* Send the packet */
>> TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr));
>> @@ -407,10 +419,11 @@ DWORD WINAPI IcmpSendEcho(
>> }
>>
>> /* Get the reply */
>> + ip_header=(struct ip*)repbuf;
>> ip_header_len=0; /* because gcc was complaining */
>> while (poll(&fdr,1,Timeout)>0) {
>> recv_time = GetTickCount();
>> - res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen);
>> + res=recvfrom(icp->sid, (char*)repbuf, repsize, 0, (struct sockaddr*)&addr, &addrlen);
>> TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr));
>> ier->Status=IP_REQ_TIMED_OUT;
>>
>> @@ -508,6 +521,12 @@ DWORD WINAPI IcmpSendEcho(
>> else Timeout = 0;
>> continue;
>> } else {
>> + /* Check free space, should be large enough for an ICMP_ECHO_REPLY and remainning icmp data */
>> + if (endbuf-(char *)ier < sizeof(struct icmp_echo_reply)+(res-ip_header_len-ICMP_MINLEN)) {
>> + res=ier-(ICMP_ECHO_REPLY *)ReplyBuffer;
>> + SetLastError(IP_GENERAL_FAILURE);
>> + goto done;
>> + }
>> /* This is a reply to our packet */
>> memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr));
>> /* Status is already set */
>> @@ -515,7 +534,7 @@ DWORD WINAPI IcmpSendEcho(
>> ier->DataSize=res-ip_header_len-ICMP_MINLEN;
>> ier->Reserved=0;
>> ier->Data=endbuf-ier->DataSize;
>> - memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize);
>> + memcpy(ier->Data, ((char *)ip_header)+ip_header_len+ICMP_MINLEN, ier->DataSize);
>> ier->Options.Ttl=ip_header->ip_ttl;
>> ier->Options.Tos=ip_header->ip_tos;
>> ier->Options.Flags=ip_header->ip_off >> 13;
>> @@ -523,7 +542,7 @@ DWORD WINAPI IcmpSendEcho(
>> if (ier->Options.OptionsSize!=0) {
>> ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize;
>> /* FIXME: We are supposed to rearrange the option's 'source route' data */
>> - memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize);
>> + memcpy(ier->Options.OptionsData, ((char *)ip_header)+ip_header_len, ier->Options.OptionsSize);
>> endbuf=(char*)ier->Options.OptionsData;
>> } else {
>> ier->Options.OptionsData=NULL;
>> @@ -531,9 +550,8 @@ DWORD WINAPI IcmpSendEcho(
>> }
>>
>> /* Prepare for the next packet */
>> + endbuf-=ier->DataSize;
>> ier++;
>> - ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY));
>> - maxlen=endbuf-(char*)ip_header;
>>
>> /* Check out whether there is more but don't wait this time */
>> Timeout=0;
>> @@ -542,6 +560,10 @@ DWORD WINAPI IcmpSendEcho(
>> res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
>> if (res==0)
>> SetLastError(IP_REQ_TIMED_OUT);
>> + else
>> + SetLastError(NO_ERROR);
>
> This hunk looks like a separate change so should be a separate patch.
> Note, in general setting last error to NO_ERROR looks wrong, though it may
> be needed in this case.
>
> Huw.
>
June 21, 2018
[PATCH 2/2] vulkan-1/tests: Add tests.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
configure | 1 +
configure.ac | 1 +
dlls/vulkan-1/Makefile.in | 1 +
dlls/vulkan-1/tests/Makefile.in | 5 +++
dlls/vulkan-1/tests/vulkan.c | 92 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 100 insertions(+)
create mode 100644 dlls/vulkan-1/tests/Makefile.in
create mode 100644 dlls/vulkan-1/tests/vulkan.c
diff --git a/configure b/configure
index bcb660d56982..ddd6db152cc9 100755
--- a/configure
+++ b/configure
@@ -19222,6 +19222,7 @@ wine_fn_config_makefile dlls/vnetbios.vxd enable_win16
wine_fn_config_makefile dlls/vssapi enable_vssapi
wine_fn_config_makefile dlls/vtdapi.vxd enable_win16
wine_fn_config_makefile dlls/vulkan-1 enable_vulkan_1
+wine_fn_config_makefile dlls/vulkan-1/tests enable_tests
wine_fn_config_makefile dlls/vwin32.vxd enable_win16
wine_fn_config_makefile dlls/w32skrnl enable_win16
wine_fn_config_makefile dlls/w32sys.dll16 enable_win16
diff --git a/configure.ac b/configure.ac
index 469fa8d72977..68f7f146ca1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3721,6 +3721,7 @@ WINE_CONFIG_MAKEFILE(dlls/vnetbios.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/vssapi)
WINE_CONFIG_MAKEFILE(dlls/vtdapi.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/vulkan-1)
+WINE_CONFIG_MAKEFILE(dlls/vulkan-1/tests)
WINE_CONFIG_MAKEFILE(dlls/vwin32.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/w32skrnl,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/w32sys.dll16,enable_win16)
diff --git a/dlls/vulkan-1/Makefile.in b/dlls/vulkan-1/Makefile.in
index 4bb8cec41287..2abc54df0e41 100644
--- a/dlls/vulkan-1/Makefile.in
+++ b/dlls/vulkan-1/Makefile.in
@@ -1,5 +1,6 @@
MODULE = vulkan-1.dll
IMPORTS = winevulkan
+IMPORTLIB = vulkan-1
C_SRCS = \
vulkan.c
diff --git a/dlls/vulkan-1/tests/Makefile.in b/dlls/vulkan-1/tests/Makefile.in
new file mode 100644
index 000000000000..c9f9f0727c80
--- /dev/null
+++ b/dlls/vulkan-1/tests/Makefile.in
@@ -0,0 +1,5 @@
+TESTDLL = vulkan-1.dll
+IMPORTS = vulkan-1
+
+C_SRCS = \
+ vulkan.c
diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c
new file mode 100644
index 000000000000..67da880fe470
--- /dev/null
+++ b/dlls/vulkan-1/tests/vulkan.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018 Józef Kucia 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 "windows.h"
+#include "wine/heap.h"
+#include "wine/vulkan.h"
+#include "wine/test.h"
+
+static VkResult create_instance(uint32_t extension_count,
+ const char * const *enabled_extensions, VkInstance *vk_instance)
+{
+ VkInstanceCreateInfo create_info;
+
+ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ create_info.pNext = NULL;
+ create_info.flags = 0;
+ create_info.pApplicationInfo = NULL;
+ create_info.enabledLayerCount = 0;
+ create_info.ppEnabledLayerNames = NULL;
+ create_info.enabledExtensionCount = extension_count;
+ create_info.ppEnabledExtensionNames = enabled_extensions;
+
+ return vkCreateInstance(&create_info, NULL, vk_instance);
+}
+
+static void test_enumerate_physical_devices(void)
+{
+ VkPhysicalDevice *vk_physical_devices;
+ VkPhysicalDeviceProperties properties;
+ VkInstance vk_instance;
+ unsigned int i;
+ uint32_t count;
+ VkResult vr;
+
+ if ((vr = create_instance(0, NULL, &vk_instance)) < 0)
+ {
+ skip("Failed to create Vulkan instance, vr %d.\n", vr);
+ return;
+ }
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+ vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+ if (!count)
+ {
+ skip("No physical devices.\n");
+ vkDestroyInstance(vk_instance, NULL);
+ return;
+ }
+
+ trace("Got %u physical device(s).\n", count);
+ vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices));
+ ok(!!vk_physical_devices, "Failed to allocate memory.\n");
+ vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+ for (i = 0; i < count; ++i)
+ {
+ vkGetPhysicalDeviceProperties(vk_physical_devices[i], &properties);
+
+ trace("Device '%s', %#x:%#x, driver version %u.%u.%u (%#x), api version %u.%u.%u.\n",
+ properties.deviceName, properties.vendorID, properties.deviceID,
+ VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion),
+ VK_VERSION_PATCH(properties.driverVersion), properties.driverVersion,
+ VK_VERSION_MAJOR(properties.apiVersion), VK_VERSION_MINOR(properties.apiVersion),
+ VK_VERSION_PATCH(properties.apiVersion));
+ }
+
+ heap_free(vk_physical_devices);
+
+ vkDestroyInstance(vk_instance, NULL);
+}
+
+START_TEST(vulkan)
+{
+ test_enumerate_physical_devices();
+}
--
2.16.4
June 21, 2018
[PATCH 1/2] wrc: Accept hyphens in identificators.
by Józef Kucia
It is a bit more permissive than it should be, hyphens should be allowed
in resource names, but not in filenames.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
I need it to add tests for vulkan-1. I would like to add some tests for
structure conversion bugs.
---
tools/wrc/parser.l | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l
index 32a231b5a2ea..0f46670288ce 100644
--- a/tools/wrc/parser.l
+++ b/tools/wrc/parser.l
@@ -402,7 +402,7 @@ static unsigned long xstrtoul(const char *nptr, char **endptr, int base)
0[oO][0-7]+[lL]? { parser_lval.num = xstrtoul(yytext+2, 0, 8);
return (yytext[yyleng-1] == 'L' || yytext[yyleng-1] == 'l') ? tLNUMBER : tNUMBER; }
-[A-Za-z_0-9./\\]+ {
+[A-Za-z_0-9./\\][A-Za-z_0-9./\\\-]* {
struct keyword *tok = iskeyword(yytext);
if(tok)
--
2.16.4
June 21, 2018
Re: [PATCH 1/2] iphlpapi: Use a standalone buffer in IcmpSendEcho().
by Huw Davies
On Fri, Jun 15, 2018 at 12:23:23PM +0800, Zhiyi Zhang wrote:
> Fix https://bugs.winehq.org/show_bug.cgi?id=43252
>
> The old implementation uses user provided buffer to receive
> packet data, which is alway not enough, causing data corruptions
> or incorrectly timeout.
>
> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
> ---
> dlls/iphlpapi/icmp.c | 38 +++++++++++++++++++++++++++-------
> dlls/iphlpapi/tests/iphlpapi.c | 21 +++++++++++++++----
> 2 files changed, 47 insertions(+), 12 deletions(-)
>
> diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
> index ebc2f2b65c..7c91443598 100644
> --- a/dlls/iphlpapi/icmp.c
> +++ b/dlls/iphlpapi/icmp.c
> @@ -113,6 +113,9 @@ typedef struct {
> #define IP_OPTS_DEFAULT 1
> #define IP_OPTS_CUSTOM 2
>
> +#define MAXIPLEN 60
> +#define MAXICMPLEN 76
Out of interest, how did you get to 76?
> +
> /* The sequence number is unique process wide, so that all threads
> * have a distinct sequence number.
> */
> @@ -270,13 +273,14 @@ DWORD WINAPI IcmpSendEcho(
> icmp_t* icp=(icmp_t*)IcmpHandle;
> unsigned char* reqbuf;
> int reqsize;
> + unsigned char* repbuf;
> + int repsize;
>
> struct icmp_echo_reply* ier;
> struct ip* ip_header;
> struct icmp* icmp_header;
> char* endbuf;
> int ip_header_len;
> - int maxlen;
> struct pollfd fdr;
> DWORD send_time,recv_time;
> struct sockaddr_in addr;
> @@ -312,6 +316,16 @@ DWORD WINAPI IcmpSendEcho(
> return 0;
> }
>
> + /* max ip header + max icmp header and error data + reply size(max 65535 on Windows) */
> + /* FIXME: request size of 65535 is not supported yet because max buffer size of raw socket on linux is 32767 */
> + repsize=MAXIPLEN+MAXICMPLEN+(ReplySize&0xFFFF);
> + repbuf=HeapAlloc(GetProcessHeap(), 0, repsize);
> + if (reqbuf==NULL) {
This should be repbuf.
> + HeapFree(GetProcessHeap(), 0, reqbuf);
> + SetLastError(ERROR_OUTOFMEMORY);
> + return 0;
> + }
> +
> icmp_header=(struct icmp*)reqbuf;
> icmp_header->icmp_type=ICMP_ECHO;
> icmp_header->icmp_code=0;
> @@ -367,9 +381,7 @@ DWORD WINAPI IcmpSendEcho(
> fdr.events = POLLIN;
> addrlen=sizeof(addr);
> ier=ReplyBuffer;
> - ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY));
> endbuf=(char *) ReplyBuffer+ReplySize;
> - maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY);
>
> /* Send the packet */
> TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr));
> @@ -407,10 +419,11 @@ DWORD WINAPI IcmpSendEcho(
> }
>
> /* Get the reply */
> + ip_header=(struct ip*)repbuf;
> ip_header_len=0; /* because gcc was complaining */
> while (poll(&fdr,1,Timeout)>0) {
> recv_time = GetTickCount();
> - res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen);
> + res=recvfrom(icp->sid, (char*)repbuf, repsize, 0, (struct sockaddr*)&addr, &addrlen);
> TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr));
> ier->Status=IP_REQ_TIMED_OUT;
>
> @@ -508,6 +521,12 @@ DWORD WINAPI IcmpSendEcho(
> else Timeout = 0;
> continue;
> } else {
> + /* Check free space, should be large enough for an ICMP_ECHO_REPLY and remainning icmp data */
> + if (endbuf-(char *)ier < sizeof(struct icmp_echo_reply)+(res-ip_header_len-ICMP_MINLEN)) {
> + res=ier-(ICMP_ECHO_REPLY *)ReplyBuffer;
> + SetLastError(IP_GENERAL_FAILURE);
> + goto done;
> + }
> /* This is a reply to our packet */
> memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr));
> /* Status is already set */
> @@ -515,7 +534,7 @@ DWORD WINAPI IcmpSendEcho(
> ier->DataSize=res-ip_header_len-ICMP_MINLEN;
> ier->Reserved=0;
> ier->Data=endbuf-ier->DataSize;
> - memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize);
> + memcpy(ier->Data, ((char *)ip_header)+ip_header_len+ICMP_MINLEN, ier->DataSize);
> ier->Options.Ttl=ip_header->ip_ttl;
> ier->Options.Tos=ip_header->ip_tos;
> ier->Options.Flags=ip_header->ip_off >> 13;
> @@ -523,7 +542,7 @@ DWORD WINAPI IcmpSendEcho(
> if (ier->Options.OptionsSize!=0) {
> ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize;
> /* FIXME: We are supposed to rearrange the option's 'source route' data */
> - memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize);
> + memcpy(ier->Options.OptionsData, ((char *)ip_header)+ip_header_len, ier->Options.OptionsSize);
> endbuf=(char*)ier->Options.OptionsData;
> } else {
> ier->Options.OptionsData=NULL;
> @@ -531,9 +550,8 @@ DWORD WINAPI IcmpSendEcho(
> }
>
> /* Prepare for the next packet */
> + endbuf-=ier->DataSize;
> ier++;
> - ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY));
> - maxlen=endbuf-(char*)ip_header;
>
> /* Check out whether there is more but don't wait this time */
> Timeout=0;
> @@ -542,6 +560,10 @@ DWORD WINAPI IcmpSendEcho(
> res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
> if (res==0)
> SetLastError(IP_REQ_TIMED_OUT);
> + else
> + SetLastError(NO_ERROR);
This hunk looks like a separate change so should be a separate patch.
Note, in general setting last error to NO_ERROR looks wrong, though it may
be needed in this case.
Huw.
June 21, 2018
[PATCH] kernel32: Implement K32EnumDeviceDrivers and K32GetDeviceDriverBaseNameA (pt. 2)
by Anthony Lauzon
I noticed my submission yesterday was a little undercooked and since I have
spent some more time on it, I thought I'd try to submit a (hopefully)
proper patch to the list. This is a rough implementation of
K32EnumDeviceDrivers and K32GetDeviceDriverBaseNameA.
June 21, 2018
Re: [PATCH v2] user32: Always release menu item in EnableMenuItem
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 21, 2018
Re: [PATCH] oleaut32: Correct some comments.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 21, 2018
Re: [PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39269
Your paranoid android.
=== wxppro (32 bit info) ===
The task timed out
June 21, 2018
[PATCH] ntdll: Implement LdrRegisterDllNotification and LdrUnregisterDllNotification.
by Alistair Leslie-Hughes
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/ntdll/loader.c | 75 +++++++++++++-
dlls/ntdll/tests/rtl.c | 261 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 332 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3e00ec6..cae9b25 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -40,6 +40,7 @@
#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/list.h"
#include "wine/server.h"
#include "ntdll_misc.h"
#include "ddk/wdm.h"
@@ -71,6 +72,13 @@ static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed
static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
+struct ldr_notification
+{
+ struct list entry;
+ PLDR_DLL_NOTIFICATION_FUNCTION callback;
+ void *context;
+};
+
static const char * const reason_names[] =
{
"PROCESS_DETACH",
@@ -342,6 +350,29 @@ static ULONG_PTR allocate_stub( const char *dll, const char *name )
static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { return 0xdeadbeef; }
#endif /* __i386__ */
+/* call ldr notifications */
+static void call_ldr_notifications( ULONG reason, LDR_MODULE *module )
+{
+ struct ldr_notification *notify, *notify_next;
+ LDR_DLL_NOTIFICATION_DATA data;
+
+ data.Loaded.Flags = 0;
+ data.Loaded.FullDllName = &module->FullDllName;
+ data.Loaded.BaseDllName = &module->BaseDllName;
+ data.Loaded.DllBase = module->BaseAddress;
+ data.Loaded.SizeOfImage = module->SizeOfImage;
+
+ LIST_FOR_EACH_ENTRY_SAFE( notify, notify_next, &ldr_notifications, struct ldr_notification, entry )
+ {
+ TRACE_(relay)("\1Call LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+
+ notify->callback(reason, &data, notify->context);
+
+ TRACE_(relay)("\1Ret LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+ }
+}
/*************************************************************************
* get_modref
@@ -1275,12 +1306,18 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
{
WINE_MODREF *prev = current_modref;
current_modref = wm;
+
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_LOADED, &wm->ldr );
status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
if (status == STATUS_SUCCESS)
+ {
wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
+ }
else
{
MODULE_InitDLL( wm, DLL_PROCESS_DETACH, lpReserved );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, &wm->ldr );
+
/* point to the name so LdrInitializeThunk can print it */
last_failed_modref = wm;
WARN("Initialization of %s failed\n", debugstr_w(wm->ldr.BaseDllName.Buffer));
@@ -1353,6 +1390,7 @@ static void process_detach(void)
mod->Flags &= ~LDR_PROCESS_ATTACHED;
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
DLL_PROCESS_DETACH, ULongToPtr(process_detaching) );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, mod );
/* Restart at head of WINE_MODREF list, as entries might have
been added and/or removed while performing the call ... */
@@ -1467,8 +1505,27 @@ NTSTATUS WINAPI LdrEnumerateLoadedModules( void *unknown, LDRENUMPROC callback,
NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FUNCTION callback,
void *context, void **cookie)
{
- FIXME( "(%04x, %p, %p, %p) stub\n", flags, callback, context, cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify;
+
+ TRACE( "(%x, %p, %p, %p)\n", flags, callback, context, cookie );
+
+ if (!callback || !cookie)
+ return STATUS_INVALID_PARAMETER;
+
+ if (flags)
+ FIXME( "ignoring flags %x\n", flags );
+
+ notify = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*notify) );
+ if (!notify) return STATUS_NO_MEMORY;
+ notify->callback = callback;
+ notify->context = context;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_add_tail( &ldr_notifications, ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ *cookie = notify;
+ return STATUS_SUCCESS;
}
/******************************************************************
@@ -1476,8 +1533,18 @@ NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FU
*/
NTSTATUS WINAPI LdrUnregisterDllNotification( void *cookie )
{
- FIXME( "(%p) stub\n", cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify = cookie;
+
+ TRACE( "(%p)\n", cookie );
+
+ if (!notify) return STATUS_INVALID_PARAMETER;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_remove( ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ RtlFreeHeap( GetProcessHeap(), 0, notify );
+ return STATUS_SUCCESS;
}
/******************************************************************
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 2e3a7de..1a9e313 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -101,6 +101,8 @@ static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, U
static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *);
static NTSTATUS (WINAPI *pRtlMakeSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
static NTSTATUS (WINAPI *pRtlAbsoluteToSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PULONG);
+static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
+static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -108,10 +110,15 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#define LEN 16
static const char* src_src = "This is a test!"; /* 16 bytes long, incl NUL */
+static WCHAR ws2_32dllW[] = {'w','s','2','_','3','2','.','d','l','l',0};
+static WCHAR nsidllW[] = {'n','s','i','.','d','l','l',0};
+static WCHAR wintrustdllW[] = {'w','i','n','t','r','u','s','t','.','d','l','l',0};
+static WCHAR crypt32dllW[] = {'c','r','y','p','t','3','2','.','d','l','l',0};
static ULONG src_aligned_block[4];
static ULONG dest_aligned_block[32];
static const char *src = (const char*)src_aligned_block;
static char* dest = (char*)dest_aligned_block;
+const WCHAR *expected_dll = nsidllW;
static void InitFunctionPtrs(void)
{
@@ -157,6 +164,8 @@ static void InitFunctionPtrs(void)
pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
pRtlMakeSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlMakeSelfRelativeSD");
pRtlAbsoluteToSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlAbsoluteToSelfRelativeSD");
+ pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification");
+ pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -2259,6 +2268,257 @@ static void test_RtlMakeSelfRelativeSD(void)
ok( status == STATUS_BAD_DESCRIPTOR_FORMAT, "got %08x\n", status );
}
+static DWORD (CALLBACK *orig_entry)(HMODULE,DWORD,LPVOID);
+static DWORD *dll_main_data;
+
+static inline void *get_rva( HMODULE module, DWORD va )
+{
+ return (void *)((char *)module + va);
+}
+
+static void CALLBACK ldr_notify_callback1(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ const IMAGE_IMPORT_DESCRIPTOR *imports;
+ const IMAGE_THUNK_DATA *import_list;
+ IMAGE_THUNK_DATA *thunk_list;
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+ ULONG size;
+ int i, j;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll))
+ return;
+
+ ok(data->Loaded.Flags == 0, "Expected flags 0, got %x\n", data->Loaded.Flags);
+ ok(!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(data->Loaded.BaseDllName->Buffer));
+ ok(!!data->Loaded.DllBase, "Expected non zero base address\n");
+ ok(data->Loaded.SizeOfImage, "Expected non zero image size\n");
+
+ /* expect module to be last module listed in LdrData load order list */
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ ok(!lstrcmpiW(mod->BaseDllName.Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(mod->BaseDllName.Buffer));
+
+ /* show that imports have already been resolved */
+ imports = RtlImageDirectoryEntryToData(data->Loaded.DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+ ok(!!imports, "Expected dll to have imports\n");
+
+ for (i = 0; imports[i].Name; i++)
+ {
+ thunk_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].FirstThunk);
+ if (imports[i].OriginalFirstThunk)
+ import_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].OriginalFirstThunk);
+ else
+ import_list = thunk_list;
+
+ for (j = 0; import_list[j].u1.Ordinal; j++)
+ {
+ ok(thunk_list[j].u1.AddressOfData > data->Loaded.SizeOfImage,
+ "Import has not been resolved: %p\n", (void*)thunk_list[j].u1.Function);
+ }
+ }
+}
+
+static void CALLBACK ldr_notify_callback2(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ *calls <<= 4;
+ *calls |= reason + 2;
+}
+
+static BOOL WINAPI fake_dll_main(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return orig_entry(instance, reason, reserved);
+}
+
+static void CALLBACK ldr_notify_callback_dll_main(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main;
+ dll_main_data = calls;
+}
+
+static BOOL WINAPI fake_dll_main_fail(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return FALSE;
+}
+
+static void CALLBACK ldr_notify_callback_fail(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main_fail;
+ dll_main_data = calls;
+}
+
+static void CALLBACK ldr_notify_callback_imports(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, crypt32dllW))
+ {
+ *calls <<= 4;
+ *calls |= 1;
+ }
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, wintrustdllW))
+ {
+ *calls <<= 4;
+ *calls |= 2;
+ }
+}
+
+static void test_LdrRegisterDllNotification(void)
+{
+ void *cookie, *cookie2;
+ NTSTATUS status;
+ HMODULE mod;
+ DWORD calls;
+
+ if (!pLdrRegisterDllNotification || !pLdrUnregisterDllNotification)
+ {
+ win_skip("Ldr(Un)RegisterDllNotification not available\n");
+ return;
+ }
+
+ mod = LoadLibraryW(expected_dll);
+ if(mod)
+ FreeLibrary(mod);
+ else
+ expected_dll = ws2_32dllW; /* XP Default */
+
+ /* generic test */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback1, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_LOADED, "Expected LDR_DLL_NOTIFICATION_REASON_LOADED, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_UNLOADED, "Expected LDR_DLL_NOTIFICATION_REASON_UNLOADED, got %x\n", calls);
+
+ /* test order of callbacks */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback2, &calls, &cookie2);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x24, "Expected order 0x24, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie2);
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_dll_main, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x42, "Expected order 0x42, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_fail, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!mod, "Expected library to fail loading\n");
+ ok(calls == 0x1342, "Expected order 0x1342, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll with dependencies */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_imports, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(wintrustdllW);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x12 || calls == 0x21, "got %x\n", calls);
+
+ FreeLibrary(mod);
+ pLdrUnregisterDllNotification(cookie);
+}
+
START_TEST(rtl)
{
InitFunctionPtrs();
@@ -2293,4 +2553,5 @@ START_TEST(rtl)
test_RtlLeaveCriticalSection();
test_LdrEnumerateLoadedModules();
test_RtlMakeSelfRelativeSD();
+ test_LdrRegisterDllNotification();
}
--
1.9.1
June 21, 2018
[PATCH 5/5] ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5712e4cc1b..2ca9cd59b0 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1352,7 +1352,8 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
(*pdata)[i].Relationship = rel;
(*pdata)[i].ProcessorMask = mask;
- /* TODO: set processor core flags */
+ if (rel == RelationProcessorCore)
+ (*pdata)[i].u.ProcessorCore.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
(*pdata)[i].u.Reserved[0] = 0;
(*pdata)[i].u.Reserved[1] = id;
*len = i+1;
--
2.14.4
June 21, 2018
[PATCH 4/5] ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 27 +++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index b16f320957..5712e4cc1b 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,17 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* Store package and core information for a logical processor. Parsing of processor
* data may happen in multiple passes; the 'id' parameter is then used to locate
* previously stored data. The type of data stored in 'id' depends on 'rel':
@@ -1377,7 +1388,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->Relationship = rel;
dataex->Size = log_proc_ex_size_plus(sizeof(PROCESSOR_RELATIONSHIP));
- dataex->u.Processor.Flags = 0; /* TODO */
+ if (rel == RelationProcessorCore)
+ dataex->u.Processor.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
+ else
+ dataex->u.Processor.Flags = 0;
dataex->u.Processor.EfficiencyClass = 0;
dataex->u.Processor.GroupCount = 1;
dataex->u.Processor.GroupMask[0].Mask = mask;
@@ -1520,17 +1534,6 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
-static DWORD count_bits(ULONG_PTR mask)
-{
- DWORD count = 0;
- while (mask > 0)
- {
- mask >>= 1;
- count++;
- }
- return count;
-}
-
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
diff --git a/include/winnt.h b/include/winnt.h
index 54bf11dabd..862cc45291 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5982,6 +5982,8 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP
RelationAll = 0xffff
} LOGICAL_PROCESSOR_RELATIONSHIP;
+#define LTP_PC_SMT 0x1
+
typedef enum _PROCESSOR_CACHE_TYPE
{
CacheUnified,
--
2.14.4
June 21, 2018
[PATCH v2 3/5] ntdll: Report physical cores once with proper thread mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 48 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 14e18dc6af..b16f320957 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1322,17 +1322,16 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
if (pdata) {
DWORD i;
- if(rel == RelationProcessorPackage){
- for(i=0; i<*len; i++)
+ for (i=0; i<*len; i++)
+ {
+ if (rel == RelationProcessorPackage && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id)
{
- if ((*pdata)[i].Relationship!=rel || (*pdata)[i].u.Reserved[1]!=id)
- continue;
-
(*pdata)[i].ProcessorMask |= mask;
return TRUE;
}
- }else
- i = *len;
+ else if (rel == RelationProcessorCore && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id)
+ return TRUE;
+ }
while(*len == *pmax_len)
{
@@ -1358,6 +1357,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->u.Processor.GroupMask[0].Mask |= mask;
return TRUE;
}
+ else if (rel == RelationProcessorCore && dataex->Relationship == rel && dataex->u.Processor.Reserved[1] == id)
+ {
+ return TRUE;
+ }
ofs += dataex->Size;
}
@@ -1554,6 +1557,9 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=beg; i<=end; i++)
{
+ DWORD phys_core = 0;
+ ULONG_PTR thread_mask = 0;
+
if(i > 8*sizeof(ULONG_PTR))
{
FIXME("skipping logical processor %d\n", i);
@@ -1574,15 +1580,35 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
}
- sprintf(name, core_info, i, "core_id");
+ /* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates
+ * by physical core. Upon enumerating a logical core in sysfs, we register a physical
+ * core and all its logical cores. In order to not report physical cores multiple
+ * times, we pass a unique physical core ID to logical_proc_info_add_by_id and let
+ * that call figure out any duplication.
+ * Obtain a unique physical core ID from the first element of thread_siblings_list.
+ * This list provides logical cores sharing the same physical core. The IDs are based
+ * on kernel cpu core numbering as opposed to a hardware core ID like provided through
+ * 'core_id', so are suitable as a unique ID.
+ */
+ sprintf(name, core_info, i, "thread_siblings_list");
f = fopen(name, "r");
if(f)
{
- fscanf(f, "%u", &r);
+ fscanf(f, "%d%c", &phys_core, &op);
+ fclose(f);
+ }
+ else phys_core = i;
+
+ /* Mask of logical threads sharing same physical core in kernel core numbering. */
+ sprintf(name, core_info, i, "thread_siblings");
+ f = fopen(name, "r");
+ if(f)
+ {
+ fscanf(f, "%lx", &thread_mask);
fclose(f);
}
- else r = i;
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, (ULONG_PTR)1 << i))
+ else thread_mask = 1<<i;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask))
{
fclose(fcpu_list);
return STATUS_NO_MEMORY;
--
2.14.4
June 21, 2018
[PATCH 2/5] ntdll: store core information by core on apple.
by Roderick Colenbrander
The id parameter can be used for core / package lookup. On Linux
we pass package or core values. On Mac, we use package for both.
Use a core identifier on Mac as well.
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e6458b98f2..14e18dc6af 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,12 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+/* Store package and core information for a logical processor. Parsing of processor
+ * data may happen in multiple passes; the 'id' parameter is then used to locate
+ * previously stored data. The type of data stored in 'id' depends on 'rel':
+ * - RelationProcessorPackage: package id ('CPU socket').
+ * - RelationProcessorCore: physical core number.
+ */
static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, DWORD *pmax_len,
LOGICAL_PROCESSOR_RELATIONSHIP rel, DWORD id, ULONG_PTR mask)
@@ -1805,6 +1811,7 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(p = 0; p < pkgs_no; ++p){
for(j = 0; j < cores_per_package && p * cores_per_package + j < cores_no; ++j){
ULONG_PTR mask = 0;
+ DWORD phys_core;
for(k = 0; k < lcpu_per_core; ++k)
mask |= (ULONG_PTR)1 << (j * lcpu_per_core + k);
@@ -1816,7 +1823,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
/* add new core */
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, p, mask))
+ phys_core = p * cores_per_package + j;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, mask))
return STATUS_NO_MEMORY;
for(i = 1; i < 5; ++i){
--
2.14.4
June 21, 2018
[PATCH 1/5] ntdll: Derive number of logical CPU cores from core mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dc0ce04f42..e6458b98f2 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1511,6 +1511,17 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
@@ -1643,7 +1654,6 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=0; i<len; i++){
if((*data)[i].Relationship == RelationProcessorCore){
all_cpus_mask |= (*data)[i].ProcessorMask;
- ++num_cpus;
}
}
}else{
@@ -1651,11 +1661,11 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*dataex) + i);
if(infoex->Relationship == RelationProcessorCore){
all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask;
- ++num_cpus;
}
i += infoex->Size;
}
}
+ num_cpus = count_bits(all_cpus_mask);
fnuma_list = fopen("/sys/devices/system/node/online", "r");
if(!fnuma_list)
--
2.14.4
June 21, 2018
[PATCH v2 0/5] ntdll: Improve logical core reporting on Linux and Mac.
by Roderick Colenbrander
Hi,
This is an updated version of the previous patchset with a few improvements
to unify some of the logic better across Linux and Mac.
The overall issue is that on Linux we report each logical core as a physical
core, so on SMT systems we report twice the number of cores. In addition we
don't properly report SMT capabilities.
The main issues are in the Linux sysfs code for parsing the CPU topology.
We use a common helper function (logical_proc_info_add_by_id) among Linux
and Mac. This is were some of the fixes need to be implemented for not
adding cores twice. (We do something similar in logical_proc_info_add_cache
in relation to parsing shared_cpu_map.)
However we use logical_proc_info_add_by_id in an inconsistent manner between
Linux and Mac code. On Linux we use different ID values (core and package),
but on Mac we re-use the package ID. The early patches rectify this and
thanks Andrew Eikum for helping to test this. The later patches fix the
Linux issues and then add proper SMT reporting flags.
Thanks,
Roderick
Roderick Colenbrander (5):
ntdll: Derive number of logical CPU cores from core mask.
ntdll: store core information by core on apple.
ntdll: Report physical cores once with proper thread mask.
ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT
cores.
ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
dlls/ntdll/nt.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 61 insertions(+), 16 deletions(-)
--
2.14.4
June 21, 2018
[PATCH v8 9/9] ntdll: Return chassis info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e622912d8a..d9fc2e6108 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -108,6 +108,17 @@ struct smbios_board {
BYTE serial;
};
+struct smbios_chassis {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE shape;
+ BYTE version;
+ BYTE serial;
+ BYTE asset_tag;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1945,12 +1956,15 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
char board_vendor[128], board_product[128], board_version[128], board_serial[128];
size_t board_vendor_len, board_product_len, board_version_len, board_serial_len;
+ char chassis_vendor[128], chassis_version[128], chassis_serial[128], chassis_asset_tag[128];
+ size_t chassis_vendor_len, chassis_version_len, chassis_serial_len, chassis_asset_tag_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
struct smbios_system *system;
struct smbios_board *board;
+ struct smbios_chassis *chassis;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
@@ -1964,6 +1978,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product));
board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version));
board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial));
+ chassis_vendor_len = get_smbios_string("/sys/class/dmi/id/chassis_vendor", S(chassis_vendor));
+ chassis_version_len = get_smbios_string("/sys/class/dmi/id/chassis_version", S(chassis_version));
+ chassis_serial_len = get_smbios_string("/sys/class/dmi/id/chassis_serial", S(chassis_serial));
+ chassis_asset_tag_len = get_smbios_string("/sys/class/dmi/id/chassis_tag", S(chassis_asset_tag));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1978,6 +1996,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += sizeof(struct smbios_board);
*required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_chassis);
+ *required_len += max(chassis_vendor_len + chassis_version_len + chassis_serial_len +
+ chassis_asset_tag_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -2064,6 +2086,33 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, board_version, board_version_len);
copy_smbios_string(&buffer, board_serial, board_serial_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ chassis = (struct smbios_chassis*)buffer;
+ chassis->type = 3;
+ chassis->length = sizeof(struct smbios_chassis);
+ chassis->handle = 0;
+ chassis->vendor = chassis_vendor_len ? ++string_count : 0;
+ chassis->shape = 0x2; /* unknown */
+ chassis->version = chassis_version_len ? ++string_count : 0;
+ chassis->serial = chassis_serial_len ? ++string_count : 0;
+ chassis->asset_tag = chassis_asset_tag_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_chassis);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, chassis_vendor, chassis_vendor_len);
+ copy_smbios_string(&buffer, chassis_version, chassis_version_len);
+ copy_smbios_string(&buffer, chassis_serial, chassis_serial_len);
+ copy_smbios_string(&buffer, chassis_asset_tag, chassis_asset_tag_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018
[PATCH v8 8/9] ntdll: Return board info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5137b8e5dc..e622912d8a 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -98,6 +98,16 @@ struct smbios_system {
BYTE serial;
};
+struct smbios_board {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE product;
+ BYTE version;
+ BYTE serial;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1933,11 +1943,14 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
size_t bios_vendor_len, bios_version_len, bios_date_len;
char system_vendor[128], system_product[128], system_version[128], system_serial[128];
size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
+ char board_vendor[128], board_product[128], board_version[128], board_serial[128];
+ size_t board_vendor_len, board_product_len, board_version_len, board_serial_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
struct smbios_system *system;
+ struct smbios_board *board;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
@@ -1947,6 +1960,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product));
system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version));
system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial));
+ board_vendor_len = get_smbios_string("/sys/class/dmi/id/board_vendor", S(board_vendor));
+ board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product));
+ board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version));
+ board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1958,6 +1975,9 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += max(system_vendor_len + system_product_len + system_version_len +
system_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_board);
+ *required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -2018,6 +2038,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, system_version, system_version_len);
copy_smbios_string(&buffer, system_serial, system_serial_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ board = (struct smbios_board*)buffer;
+ board->type = 2;
+ board->length = sizeof(struct smbios_board);
+ board->handle = 0;
+ board->vendor = board_vendor_len ? ++string_count : 0;
+ board->product = board_product_len ? ++string_count : 0;
+ board->version = board_version_len ? ++string_count : 0;
+ board->serial = board_serial_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_board);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, board_vendor, board_vendor_len);
+ copy_smbios_string(&buffer, board_product, board_product_len);
+ copy_smbios_string(&buffer, board_version, board_version_len);
+ copy_smbios_string(&buffer, board_serial, board_serial_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018
[PATCH v8 7/9] ntdll: Return system info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index c46c3cd01d..5137b8e5dc 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -88,6 +88,16 @@ struct smbios_bios {
UINT64 characteristics;
};
+struct smbios_system {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE product;
+ BYTE version;
+ BYTE serial;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1921,15 +1931,22 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
{
char bios_vendor[128], bios_version[128], bios_date[128];
size_t bios_vendor_len, bios_version_len, bios_date_len;
+ char system_vendor[128], system_product[128], system_version[128], system_serial[128];
+ size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
+ struct smbios_system *system;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version));
bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date));
+ system_vendor_len = get_smbios_string("/sys/class/dmi/id/sys_vendor", S(system_vendor));
+ system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product));
+ system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version));
+ system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1937,6 +1954,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += sizeof(struct smbios_bios);
*required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
+ *required_len += sizeof(struct smbios_system);
+ *required_len += max(system_vendor_len + system_product_len + system_version_len +
+ system_serial_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -1971,6 +1992,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, bios_version, bios_version_len);
copy_smbios_string(&buffer, bios_date, bios_date_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ system = (struct smbios_system*)buffer;
+ system->type = 1;
+ system->length = sizeof(struct smbios_system);
+ system->handle = 0;
+ system->vendor = system_vendor_len ? ++string_count : 0;
+ system->product = system_product_len ? ++string_count : 0;
+ system->version = system_version_len ? ++string_count : 0;
+ system->serial = system_serial_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_system);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, system_vendor, system_vendor_len);
+ copy_smbios_string(&buffer, system_product, system_product_len);
+ copy_smbios_string(&buffer, system_version, system_version_len);
+ copy_smbios_string(&buffer, system_serial, system_serial_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018
[PATCH v8 6/9] kernel32: Connect GetSystemFirmwareTable to NtQuerySystemInformation
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/kernel32/cpu.c | 29 +++++++++++++++++++++++++++++
dlls/kernel32/process.c | 10 ----------
dlls/kernel32/tests/version.c | 2 +-
3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c
index ec1fd0f90d..8397fbe729 100644
--- a/dlls/kernel32/cpu.c
+++ b/dlls/kernel32/cpu.c
@@ -336,3 +336,32 @@ DWORD64 WINAPI GetEnabledXStateFeatures(void)
FIXME("\n");
return 0;
}
+
+/***********************************************************************
+ * GetSystemFirmwareTable (KERNEL32.@)
+ */
+UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, void *buffer, DWORD size)
+{
+ ULONG buffer_size = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer) + size;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), 0, buffer_size);
+ NTSTATUS status;
+
+ if (!sfti)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
+
+ sfti->ProviderSignature = provider;
+ sfti->Action = SystemFirmwareTable_Get;
+ sfti->TableID = id;
+
+ status = NtQuerySystemInformation(SystemFirmwareTableInformation, sfti, buffer_size, &buffer_size);
+ buffer_size -= FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+ if (buffer_size <= size)
+ memcpy(buffer, sfti->TableBuffer, buffer_size);
+
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ HeapFree(GetProcessHeap(), 0, sfti);
+ return buffer_size;
+}
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index ff56e9a692..6adf08d257 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -4126,16 +4126,6 @@ HRESULT WINAPI UnregisterApplicationRestart(void)
return S_OK;
}
-/***********************************************************************
- * GetSystemFirmwareTable (KERNEL32.@)
- */
-UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, PVOID buffer, DWORD size)
-{
- FIXME("(%d %d %p %d):stub\n", provider, id, buffer, size);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
struct proc_thread_attr
{
DWORD_PTR attr;
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c
index 08e8f0fb58..e33ce9cd42 100644
--- a/dlls/kernel32/tests/version.c
+++ b/dlls/kernel32/tests/version.c
@@ -717,7 +717,7 @@ void test_GetSystemFirmwareTable(void)
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len);
if (expected_len == 0) /* xp, 2003 */
{
- skip("SystemFirmwareTableInformation is not available\n");
+ win_skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
}
--
2.17.1
June 21, 2018
[PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 171 ++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/tests/info.c | 11 ++-
2 files changed, 180 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dc0ce04f42..c46c3cd01d 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -66,6 +66,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+#include "pshpack1.h"
+
+struct smbios_prologue {
+ BYTE calling_method;
+ BYTE major_version;
+ BYTE minor_version;
+ BYTE revision;
+ DWORD length;
+};
+
+struct smbios_bios {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE version;
+ WORD start;
+ BYTE date;
+ BYTE size;
+ UINT64 characteristics;
+};
+
+#include "poppack.h"
+
+/* Firmware table providers */
+#define ACPI 0x41435049
+#define FIRM 0x4649524D
+#define RSMB 0x52534D42
+
/*
* Token
*/
@@ -1850,6 +1879,126 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
}
#endif
+static inline void copy_smbios_string(char **buffer, char *s, size_t len)
+{
+ if (!len) return;
+ strcpy(*buffer, s);
+ *buffer += len + 1;
+}
+
+#ifdef linux
+
+static size_t get_smbios_string(const char *path, char *str, size_t size)
+{
+ FILE *file;
+ size_t len;
+
+ if (!(file = fopen(path, "r")))
+ return 0;
+
+ len = fread(str, 1, size - 1, file);
+ fclose(file);
+
+ if (len >= 1 && str[len - 1] == '\n')
+ {
+ str[len - 1] = 0;
+ len--;
+ }
+ else
+ {
+ str[len] = 0;
+ }
+
+ return len;
+}
+
+static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti,
+ ULONG available_len, ULONG *required_len)
+{
+ switch (sfti->ProviderSignature)
+ {
+ case RSMB:
+ {
+ char bios_vendor[128], bios_version[128], bios_date[128];
+ size_t bios_vendor_len, bios_version_len, bios_date_len;
+ char *buffer = (char*)sfti->TableBuffer;
+ BYTE string_count;
+ struct smbios_prologue *prologue;
+ struct smbios_bios *bios;
+
+#define S(s) s, sizeof(s)
+ bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
+ bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version));
+ bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date));
+#undef S
+
+ *required_len = sizeof(struct smbios_prologue);
+
+ *required_len += sizeof(struct smbios_bios);
+ *required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
+
+ sfti->TableBufferLength = *required_len;
+
+ *required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+
+ if (available_len < *required_len)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ prologue = (struct smbios_prologue*)buffer;
+ prologue->calling_method = 0;
+ prologue->major_version = 2;
+ prologue->minor_version = 0;
+ prologue->revision = 0;
+ prologue->length = sfti->TableBufferLength - sizeof(struct smbios_prologue);
+ buffer += sizeof(struct smbios_prologue);
+
+ string_count = 0;
+ bios = (struct smbios_bios*)buffer;
+ bios->type = 0;
+ bios->length = sizeof(struct smbios_bios);
+ bios->handle = 0;
+ bios->vendor = bios_vendor_len ? ++string_count : 0;
+ bios->version = bios_version_len ? ++string_count : 0;
+ bios->start = 0;
+ bios->date = bios_date_len ? ++string_count : 0;
+ bios->size = 0;
+ bios->characteristics = 0x4; /* not supported */
+ buffer += sizeof(struct smbios_bios);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, bios_vendor, bios_vendor_len);
+ copy_smbios_string(&buffer, bios_version, bios_version_len);
+ copy_smbios_string(&buffer, bios_date, bios_date_len);
+ memset(buffer, 0, 1);
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ }
+
+ return STATUS_SUCCESS;
+ }
+ default:
+ {
+ FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ }
+}
+
+#else
+
+static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti,
+ ULONG available_len, ULONG *required_len)
+{
+ FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
+ sfti->TableBufferLength = 0;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+#endif
+
/******************************************************************************
* NtQuerySystemInformation [NTDLL.@]
* ZwQuerySystemInformation [NTDLL.@]
@@ -2359,6 +2508,28 @@ NTSTATUS WINAPI NtQuerySystemInformation(
else ret = STATUS_INFO_LENGTH_MISMATCH;
}
break;
+ case SystemFirmwareTableInformation:
+ {
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = (SYSTEM_FIRMWARE_TABLE_INFORMATION*)SystemInformation;
+ len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+ if (Length < len)
+ {
+ ret = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ switch (sfti->Action)
+ {
+ case SystemFirmwareTable_Get:
+ ret = get_firmware_info(sfti, Length, &len);
+ break;
+ default:
+ len = 0;
+ ret = STATUS_NOT_IMPLEMENTED;
+ FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
+ }
+ }
+ break;
default:
FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
SystemInformationClass,SystemInformation,Length,ResultLength);
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 9e12a013cf..29af0e3d90 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -59,6 +59,12 @@ static DWORD one_before_last_pid = 0;
#define FIRM 0x4649524D
#define RSMB 0x52534D42
+#ifdef linux
+static const int firmware_todo = 0;
+#else
+static const int firmware_todo = 1;
+#endif
+
static BOOL InitFunctionPtrs(void)
{
/* All needed functions are NT based, so using GetModuleHandle is a good check */
@@ -842,12 +848,11 @@ static void test_query_firmware(void)
ok(!!sfti, "Failed to allocate memory\n");
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1);
-todo_wine
ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */,
"Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
if (len1 == 0) /* xp, 2003 */
{
- skip("SystemFirmwareTableInformation is not available\n");
+ win_skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
}
@@ -862,6 +867,7 @@ todo_wine
sfti->TableID = 0;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+todo_wine_if(firmware_todo)
ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status);
ok(len1 >= 16, "Expected length >= 16, got %u\n", len1);
ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength);
@@ -873,6 +879,7 @@ todo_wine
{
sfti->TableID = i;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2);
+todo_wine_if(firmware_todo)
ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status);
ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2);
ok(sfti->TableBufferLength == len1 - 16,
--
2.17.1
June 21, 2018
[PATCH v8 4/9] kernel32/tests: Add GetSystemFirmwareTable tests
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/kernel32/tests/version.c | 41 +++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c
index eb78a383d2..08e8f0fb58 100644
--- a/dlls/kernel32/tests/version.c
+++ b/dlls/kernel32/tests/version.c
@@ -26,11 +26,17 @@
#include "winternl.h"
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
+static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
#define GET_PROC(func) \
p##func = (void *)GetProcAddress(hmod, #func);
+/* Firmware table providers */
+#define ACPI 0x41435049
+#define FIRM 0x4649524D
+#define RSMB 0x52534D42
+
static void init_function_pointers(void)
{
HMODULE hmod;
@@ -41,6 +47,7 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("ntdll.dll");
+ GET_PROC(NtQuerySystemInformation);
GET_PROC(RtlGetVersion);
}
@@ -697,6 +704,39 @@ static void test_VerifyVersionInfo(void)
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
}
+void test_GetSystemFirmwareTable(void)
+{
+ ULONG expected_len, i;
+ UINT len;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16);
+ UCHAR *smbios_table = NULL;
+
+ ok(!!sfti, "Failed to allocate memory\n");
+ sfti->ProviderSignature = RSMB;
+ sfti->Action = SystemFirmwareTable_Get;
+ pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len);
+ if (expected_len == 0) /* xp, 2003 */
+ {
+ skip("SystemFirmwareTableInformation is not available\n");
+ HeapFree(GetProcessHeap(), 0, sfti);
+ return;
+ }
+ sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
+ ok(!!sfti, "Failed to allocate memory\n");
+ pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
+
+ expected_len -= 16;
+ smbios_table = HeapAlloc(GetProcessHeap(), 0, expected_len);
+ for (i = 0; i < 100; i++)
+ {
+ len = GetSystemFirmwareTable(RSMB, i, smbios_table, expected_len);
+ ok(len == expected_len, "Table %u: Expected length %u, got %u\n", i, expected_len, len);
+ }
+
+ HeapFree(GetProcessHeap(), 0, sfti);
+ HeapFree(GetProcessHeap(), 0, smbios_table);
+}
+
START_TEST(version)
{
init_function_pointers();
@@ -704,4 +744,5 @@ START_TEST(version)
test_GetProductInfo();
test_GetVersionEx();
test_VerifyVersionInfo();
+ test_GetSystemFirmwareTable();
}
--
2.17.1
June 21, 2018
[PATCH v8 3/9] ntdll/tests: Add SystemFirmwareTableInformation tests
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/tests/info.c | 60 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index b18f0d39d9..9e12a013cf 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -54,6 +54,11 @@ static DWORD one_before_last_pid = 0;
} \
} while(0)
+/* Firmware table providers */
+#define ACPI 0x41435049
+#define FIRM 0x4649524D
+#define RSMB 0x52534D42
+
static BOOL InitFunctionPtrs(void)
{
/* All needed functions are NT based, so using GetModuleHandle is a good check */
@@ -826,6 +831,57 @@ static void test_query_logicalprocex(void)
}
}
+static void test_query_firmware(void)
+{
+ ULONG len1, len2;
+ NTSTATUS status;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
+ int i;
+
+ sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16);
+ ok(!!sfti, "Failed to allocate memory\n");
+
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1);
+todo_wine
+ ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */,
+ "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+ if (len1 == 0) /* xp, 2003 */
+ {
+ skip("SystemFirmwareTableInformation is not available\n");
+ HeapFree(GetProcessHeap(), 0, sfti);
+ return;
+ }
+ ok(len1 == 16, "Expected length 16, got %u\n", len1);
+
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+ ok(status == STATUS_NOT_IMPLEMENTED, "Expected STATUS_NOT_IMPLEMENTED, got %08x\n", status);
+ ok(len1 == 0, "Expected length 0, got %u\n", len1);
+
+ sfti->ProviderSignature = RSMB;
+ sfti->Action = SystemFirmwareTable_Get;
+ sfti->TableID = 0;
+
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+ ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status);
+ ok(len1 >= 16, "Expected length >= 16, got %u\n", len1);
+ ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength);
+
+ sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, len1);
+ ok(!!sfti, "Failed to allocate memory\n");
+
+ for (i = 0; i < 100; i++)
+ {
+ sfti->TableID = i;
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2);
+ ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status);
+ ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2);
+ ok(sfti->TableBufferLength == len1 - 16,
+ "Table %u: Expected length %u, got %u\n", i, len1 - 16, sfti->TableBufferLength);
+ }
+
+ HeapFree(GetProcessHeap(), 0, sfti);
+}
+
static void test_query_processor_power_info(void)
{
NTSTATUS status;
@@ -2271,6 +2327,10 @@ START_TEST(info)
trace("Starting test_process_debug_flags()\n");
test_query_process_debug_flags(argc, argv);
+ /* 0x4C SystemFirmwareTableInformation */
+ trace("Starting test_query_firmware()\n");
+ test_query_firmware();
+
/* belongs to its own file */
trace("Starting test_readvirtualmemory()\n");
test_readvirtualmemory();
--
2.17.1
June 21, 2018
[PATCH v8 2/9] include: Add SYSTEM_FIRMWARE_TABLE_INFORMATION to winternl.h
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
include/winternl.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/include/winternl.h b/include/winternl.h
index 58c475dfff..6e0bd987b6 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1579,6 +1579,23 @@ typedef struct _SYSTEM_TIME_ADJUSTMENT {
BOOLEAN TimeAdjustmentDisabled;
} SYSTEM_TIME_ADJUSTMENT, *PSYSTEM_TIME_ADJUSTMENT;
+typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION
+{
+ SystemFirmwareTable_Enumerate = 0,
+ SystemFirmwareTable_Get = 1
+} SYSTEM_FIRMWARE_TABLE_ACTION, *PSYSTEM_FIRMWARE_TABLE_ACTION;
+
+/* System Information Class 0x4C */
+
+typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
+{
+ ULONG ProviderSignature;
+ SYSTEM_FIRMWARE_TABLE_ACTION Action;
+ ULONG TableID;
+ ULONG TableBufferLength;
+ UCHAR TableBuffer[1];
+} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION;
+
typedef struct _TIME_FIELDS
{ CSHORT Year;
CSHORT Month;
--
2.17.1
June 21, 2018
[PATCH v8 1/9] ntdll/tests: Skip map protection tests when access is denied
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/tests/info.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 6c93c3cd58..b18f0d39d9 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1789,6 +1789,10 @@ static void test_mapprotection(void)
}
ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &flags, sizeof(flags) );
+ if (status == STATUS_ACCESS_DENIED) {
+ skip("Access to set ProcessExecuteFlags denied\n");
+ return;
+ }
ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
size.u.LowPart = 0x2000;
--
2.17.1
June 21, 2018
[PATCH] oleaut32: Correct some comments.
by Zebediah Figura
This corresponds to 652ec646ad3 affecting widl.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/oleaut32/typelib.c | 2 +-
dlls/oleaut32/typelib.h | 17 ++++++++---------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 4ee6aa540d..9b1c782e8d 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -2675,7 +2675,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
- ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
+ ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft;
if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
TYPEDESC tmp;
MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h
index c404b3d311..7699a9a1f3 100644
--- a/dlls/oleaut32/typelib.h
+++ b/dlls/oleaut32/typelib.h
@@ -142,11 +142,11 @@ typedef struct tagMSFT_TypeInfoBase {
INT helpcontext; /* */
INT oCustData; /* offset in customer data table */
#ifdef WORDS_BIGENDIAN
- INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cbSizeVft; /* virtual table size, including inherits */
INT16 cImplTypes; /* nr of implemented interfaces */
#else
INT16 cImplTypes; /* nr of implemented interfaces */
- INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cbSizeVft; /* virtual table size, including inherits */
#endif
/*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */
@@ -155,10 +155,8 @@ typedef struct tagMSFT_TypeInfoBase {
/* if coclass: offset in reftable */
/* if interface: reference to inherited if */
/* if module: offset to dllname in name table */
- INT datatype2; /* if 0x8000, entry above is valid */
- /* actually dunno */
- /* else it is zero? */
- /* if interface: inheritance level | no of inherited funcs */
+ INT datatype2; /* for interfaces: hiword is num of inherited funcs */
+ /* loword is num of inherited interfaces */
INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase;
@@ -281,9 +279,10 @@ typedef struct {
to the typeinfo itself or to a member of
the typeinfo */
INT next_hash; /* offset to next name in the hash bucket */
- INT namelen; /* only lower 8 bits are valid,
- lower-middle 8 bits are unknown (flags?),
- upper 16 bits are hash code */
+ INT namelen; /* only lower 8 bits are valid */
+ /* 0x1000 if name is only used once as a variable name */
+ /* 0x2000 if name is a variable in an enumeration */
+ /* 0x3800 if name is typeinfo name */
} MSFT_NameIntro;
/* the custom data table directory has entries like this */
typedef struct {
--
2.17.0
June 21, 2018
K32EnumDeviceDrivers Patch
by Anthony Lauzon
Hi All,
I've been hacking away at K32EnumDeviceDrivers trying to get it to properly
handle calls, and have made some decent progress that maybe some of you who
are experts can finish. The reason why I am trying to implement
K32EnumDeviceDrivers is that Creative's E-MU Emulator X3 crashes when
trying to call it. I've managed to get the app one step closer to
launching with this K32EnumDeviceDrivers implementation, which does in fact
enumerate the devices, and am now stuck on a different error. I hope this
patch is of some utility to you all.
June 20, 2018
[PATCH 5/5] d3dx10: Turn some ERR() into WARN().
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
They can be triggered by the application and, indeed, some appeared in
the tests.
dlls/d3dx10_43/async.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c
index 1555a3d11e4..c7d80c9db46 100644
--- a/dlls/d3dx10_43/async.c
+++ b/dlls/d3dx10_43/async.c
@@ -115,7 +115,7 @@ static HRESULT WINAPI filedataloader_Load(ID3DX10DataLoader *iface)
CloseHandle(file);
if (!ret)
{
- ERR("Failed to read file contents.\n");
+ WARN("Failed to read file contents.\n");
HeapFree(GetProcessHeap(), 0, data);
return E_FAIL;
}
@@ -175,7 +175,7 @@ static HRESULT WINAPI resourcedataloader_Load(ID3DX10DataLoader *iface)
hglobal = LoadResource(loader->u.resource.module, loader->u.resource.rsrc);
if (!hglobal)
{
- ERR("Failed to load resource.\n");
+ WARN("Failed to load resource.\n");
return E_FAIL;
}
@@ -349,7 +349,7 @@ HRESULT WINAPI D3DX10CreateAsyncResourceLoaderA(HMODULE module, const char *reso
if (!(rsrc = FindResourceA(module, resource, (const char *)RT_RCDATA)))
{
- ERR("Failed to find resource.\n");
+ WARN("Failed to find resource.\n");
HeapFree(GetProcessHeap(), 0, object);
return D3DX10_ERR_INVALID_DATA;
}
@@ -381,7 +381,7 @@ HRESULT WINAPI D3DX10CreateAsyncResourceLoaderW(HMODULE module, const WCHAR *res
if (!(rsrc = FindResourceW(module, resource, (const WCHAR *)RT_RCDATA)))
{
- ERR("Failed to find resource.\n");
+ WARN("Failed to find resource.\n");
HeapFree(GetProcessHeap(), 0, object);
return D3DX10_ERR_INVALID_DATA;
}
--
2.16.4
June 20, 2018
[PATCH v2 resend 4/5] wined3d: Declare the correct number and type of fragment shader color outputs.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
dlls/wined3d/glsl_shader.c | 128 +++++++++++++++++++++++++++++++++++++++------
1 file changed, 111 insertions(+), 17 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index cd4780a6419..d5dc8be136a 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3318,12 +3318,12 @@ static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param
shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
}
-static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param,
+static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *buffer, const char *arg,
enum wined3d_component_type dst_type, enum wined3d_component_type src_type)
{
if (dst_type == src_type)
{
- string_buffer_sprintf(dst_param, "%s", src_param);
+ string_buffer_sprintf(buffer, "%s", arg);
return;
}
@@ -3332,10 +3332,10 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
switch (dst_type)
{
case WINED3D_TYPE_INT:
- string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
+ string_buffer_sprintf(buffer, "floatBitsToInt(%s)", arg);
return;
case WINED3D_TYPE_UINT:
- string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
+ string_buffer_sprintf(buffer, "floatBitsToUint(%s)", arg);
return;
default:
break;
@@ -3344,18 +3344,18 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
if (src_type == WINED3D_TYPE_UINT && dst_type == WINED3D_TYPE_FLOAT)
{
- string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param);
+ string_buffer_sprintf(buffer, "uintBitsToFloat(%s)", arg);
return;
}
if (src_type == WINED3D_TYPE_INT && dst_type == WINED3D_TYPE_FLOAT)
{
- string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param);
+ string_buffer_sprintf(buffer, "intBitsToFloat(%s)", arg);
return;
}
FIXME("Unhandled cast from %#x to %#x.\n", src_type, dst_type);
- string_buffer_sprintf(dst_param, "%s", src_param);
+ string_buffer_sprintf(buffer, "%s", arg);
}
/* From a given parameter token, generate the corresponding GLSL string.
@@ -7616,9 +7616,48 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n");
}
+static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buffer,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_shader *shader,
+ struct wined3d_string_buffer_list *string_buffers)
+{
+ const struct wined3d_shader_signature *output_signature = &shader->output_signature;
+ struct wined3d_string_buffer *src, *assignment;
+ unsigned int i;
+
+ if (output_signature->element_count)
+ {
+ src = string_buffer_get(string_buffers);
+ assignment = string_buffer_get(string_buffers);
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
+
+ /* register_idx is set to ~0u for non-color outputs. */
+ if (output->register_idx == ~0u)
+ continue;
+ shader_addline(buffer, "color_out%u = ", output->semantic_idx);
+ string_buffer_sprintf(src, "ps_out[%u]", output->semantic_idx);
+ shader_glsl_sprintf_cast(assignment, src->buffer, output->component_type, WINED3D_TYPE_FLOAT);
+ shader_addline(buffer, "%s;\n", assignment->buffer);
+ }
+ string_buffer_release(string_buffers, src);
+ string_buffer_release(string_buffers, assignment);
+ }
+ else
+ {
+ DWORD mask = shader->reg_maps.rt_mask;
+
+ while (mask)
+ {
+ i = wined3d_bit_scan(&mask);
+ shader_addline(buffer, "color_out%u = ps_out[%u];\n", i, i);
+ }
+ }
+}
+
static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info,
struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
- const struct ps_compile_args *args)
+ const struct ps_compile_args *args, struct wined3d_string_buffer_list *string_buffers)
{
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
@@ -7637,6 +7676,26 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in
if (reg_maps->sample_mask)
shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
+
+ if (!needs_legacy_glsl_syntax(gl_info))
+ shader_glsl_generate_color_output(buffer, gl_info, shader, string_buffers);
+}
+
+static const char *shader_glsl_get_ps_output_format(enum wined3d_component_type component_type)
+{
+ static const char formats[][6] =
+ {
+ "", /* WINED3D_TYPE_UNKNOWN */
+ "uvec4", /* WINED3D_TYPE_UINT */
+ "ivec4", /* WINED3D_TYPE_INT */
+ "vec4", /* WINED3D_TYPE_FLOAT */
+ };
+ if (component_type < WINED3D_TYPE_UNKNOWN || component_type > WINED3D_TYPE_FLOAT)
+ {
+ WARN("Unexpected component_type %#x.\n", component_type);
+ return formats[WINED3D_TYPE_FLOAT];
+ }
+ return formats[component_type];
}
/* Context activation is done by the caller. */
@@ -7819,9 +7878,35 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
if (!needs_legacy_glsl_syntax(gl_info))
{
- if (shader_glsl_use_explicit_attrib_location(gl_info))
- shader_addline(buffer, "layout(location = 0) ");
- shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers);
+ const struct wined3d_shader_signature *output_signature = &shader->output_signature;
+
+ shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.buffers);
+ if (output_signature->element_count)
+ {
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
+
+ if (output->register_idx == ~0u)
+ continue;
+ if (shader_glsl_use_explicit_attrib_location(gl_info))
+ shader_addline(buffer, "layout(location = %u) ", output->semantic_idx);
+ shader_addline(buffer, "out %s color_out%u;\n",
+ shader_glsl_get_ps_output_format(output->component_type), output->semantic_idx);
+ }
+ }
+ else
+ {
+ DWORD mask = reg_maps->rt_mask;
+
+ while (mask)
+ {
+ i = wined3d_bit_scan(&mask);
+ if (shader_glsl_use_explicit_attrib_location(gl_info))
+ shader_addline(buffer, "layout(location = %u) ", i);
+ shader_addline(buffer, "out vec4 color_out%u;\n", i);
+ }
+ }
}
if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants)
@@ -7906,7 +7991,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
/* In SM4+ the shader epilogue is generated by the "ret" instruction. */
if (reg_maps->shader_version.major < 4)
- shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args);
+ shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args, string_buffers);
shader_addline(buffer, "}\n");
@@ -8403,7 +8488,7 @@ static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_con
switch (shader->reg_maps.shader_version.type)
{
case WINED3D_SHADER_TYPE_PIXEL:
- shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args);
+ shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args, priv->string_buffers);
break;
case WINED3D_SHADER_TYPE_VERTEX:
shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, priv->cur_vs_args);
@@ -9539,9 +9624,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
if (!needs_legacy_glsl_syntax(gl_info))
{
+ shader_addline(buffer, "vec4 ps_out[1];\n");
if (shader_glsl_use_explicit_attrib_location(gl_info))
shader_addline(buffer, "layout(location = 0) ");
- shader_addline(buffer, "out vec4 ps_out[1];\n");
+ shader_addline(buffer, "out vec4 color_out0;\n");
}
shader_addline(buffer, "vec4 tmp0, tmp1;\n");
@@ -9881,6 +9967,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
shader_glsl_generate_fog_code(buffer, gl_info, settings->fog);
shader_glsl_generate_alpha_test(buffer, gl_info, alpha_test_func);
+ if (!needs_legacy_glsl_syntax(gl_info))
+ shader_addline(buffer, "color_out0 = ps_out[0];\n");
shader_addline(buffer, "}\n");
@@ -10422,13 +10510,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
}
}
checkGLcall("glBindAttribLocation");
- string_buffer_release(&priv->string_buffers, tmp_name);
if (!needs_legacy_glsl_syntax(gl_info))
{
- GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out"));
- checkGLcall("glBindFragDataLocation");
+ for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i)
+ {
+ string_buffer_sprintf(tmp_name, "color_out%u", i);
+ GL_EXTCALL(glBindFragDataLocation(program_id, i, tmp_name->buffer));
+ checkGLcall("glBindFragDataLocation");
+ }
}
+ string_buffer_release(&priv->string_buffers, tmp_name);
}
if (hshader)
@@ -12796,6 +12888,8 @@ static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter
shader_glsl_add_version_declaration(buffer, gl_info);
shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type);
declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
+ /* TODO: Declare the out variable with the correct type (and put it in the
+ * blitter args). */
if (!needs_legacy_glsl_syntax(gl_info))
shader_addline(buffer, "out vec4 ps_out[1];\n");
--
2.16.4
June 20, 2018
[PATCH v2 3/5] wined3d: Mostly get rid of enum wined3d_data_type.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2-ish: Leave the enum around only for the semantic data type /
shader_dump_decl_usage().
dlls/wined3d/glsl_shader.c | 100 ++++++++++++++++++++---------------------
dlls/wined3d/shader.c | 45 +++++++++++++------
dlls/wined3d/shader_sm1.c | 14 +++---
dlls/wined3d/shader_sm4.c | 56 +++++++++++------------
dlls/wined3d/wined3d_private.h | 4 +-
5 files changed, 117 insertions(+), 102 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index f1f3020d53d..cd4780a6419 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -88,7 +88,7 @@ struct glsl_sample_function
struct wined3d_string_buffer *name;
unsigned int coord_mask;
unsigned int deriv_mask;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
BOOL output_single_component;
unsigned int offset_size;
};
@@ -2522,17 +2522,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
switch (reg_maps->resource_info[entry->resource_idx].data_type)
{
- case WINED3D_DATA_FLOAT:
- case WINED3D_DATA_UNORM:
- case WINED3D_DATA_SNORM:
+ case WINED3D_TYPE_FLOAT:
sampler_type_prefix = "";
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
sampler_type_prefix = "i";
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
sampler_type_prefix = "u";
break;
@@ -2640,19 +2638,17 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
switch (reg_maps->uav_resource_info[i].data_type)
{
- case WINED3D_DATA_FLOAT:
- case WINED3D_DATA_UNORM:
- case WINED3D_DATA_SNORM:
+ case WINED3D_TYPE_FLOAT:
image_type_prefix = "";
read_format = "r32f";
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
image_type_prefix = "i";
read_format = "r32i";
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
image_type_prefix = "u";
read_format = "r32ui";
break;
@@ -2848,7 +2844,7 @@ static void shader_glsl_fixup_scalar_register_variable(char *register_name,
/** Writes the GLSL variable name that corresponds to the register that the
* DX opcode parameter is trying to access */
static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg,
- enum wined3d_data_type data_type, char *register_name, BOOL *is_color,
+ enum wined3d_component_type data_type, char *register_name, BOOL *is_color,
const struct wined3d_shader_instruction *ins)
{
/* oPos, oFog and oPts in D3D */
@@ -3084,16 +3080,16 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
case WINED3D_IMMCONST_SCALAR:
switch (data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
sprintf(register_name, "uintBitsToFloat(%#xu)", reg->u.immconst_data[0]);
else
wined3d_ftoa(*(const float *)reg->u.immconst_data, register_name);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
sprintf(register_name, "%#x", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
sprintf(register_name, "%#xu", reg->u.immconst_data[0]);
break;
default:
@@ -3105,7 +3101,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
case WINED3D_IMMCONST_VEC4:
switch (data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
{
sprintf(register_name, "uintBitsToFloat(uvec4(%#xu, %#xu, %#xu, %#xu))",
@@ -3122,12 +3118,12 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
}
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
@@ -3323,22 +3319,22 @@ static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param
}
static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param,
- enum wined3d_data_type dst_data_type, enum wined3d_data_type src_data_type)
+ enum wined3d_component_type dst_type, enum wined3d_component_type src_type)
{
- if (dst_data_type == src_data_type)
+ if (dst_type == src_type)
{
string_buffer_sprintf(dst_param, "%s", src_param);
return;
}
- if (src_data_type == WINED3D_DATA_FLOAT)
+ if (src_type == WINED3D_TYPE_FLOAT)
{
- switch (dst_data_type)
+ switch (dst_type)
{
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
return;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
return;
default:
@@ -3346,19 +3342,19 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
}
}
- if (src_data_type == WINED3D_DATA_UINT && dst_data_type == WINED3D_DATA_FLOAT)
+ if (src_type == WINED3D_TYPE_UINT && dst_type == WINED3D_TYPE_FLOAT)
{
string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param);
return;
}
- if (src_data_type == WINED3D_DATA_INT && dst_data_type == WINED3D_DATA_FLOAT)
+ if (src_type == WINED3D_TYPE_INT && dst_type == WINED3D_TYPE_FLOAT)
{
string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param);
return;
}
- FIXME("Unhandled cast from %#x to %#x.\n", src_data_type, dst_data_type);
+ FIXME("Unhandled cast from %#x to %#x.\n", src_type, dst_type);
string_buffer_sprintf(dst_param, "%s", src_param);
}
@@ -3367,11 +3363,11 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
* caller needs this information as well. */
static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instruction *ins,
const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src,
- enum wined3d_data_type data_type)
+ enum wined3d_component_type data_type)
{
struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
struct wined3d_string_buffer *reg_name = string_buffer_get(priv->string_buffers);
- enum wined3d_data_type param_data_type;
+ enum wined3d_component_type param_data_type;
BOOL is_color = FALSE;
char swizzle_str[6];
@@ -3396,10 +3392,10 @@ static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instructio
case WINED3DSPR_PRIMID:
case WINED3DSPR_THREADGROUPID:
case WINED3DSPR_THREADID:
- param_data_type = WINED3D_DATA_INT;
+ param_data_type = WINED3D_TYPE_INT;
break;
default:
- param_data_type = WINED3D_DATA_FLOAT;
+ param_data_type = WINED3D_TYPE_FLOAT;
break;
}
@@ -3434,7 +3430,7 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *
/* Append the destination part of the instruction to the buffer, return the effective write mask */
static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer,
const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst,
- enum wined3d_data_type data_type)
+ enum wined3d_component_type data_type)
{
struct glsl_dst_param glsl_dst;
DWORD mask;
@@ -3443,15 +3439,15 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer,
{
switch (data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
shader_addline(buffer, "%s%s = %s(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
shader_addline(buffer, "%s%s = %sintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
shader_addline(buffer, "%s%s = %suintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
@@ -4013,7 +4009,7 @@ static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str);
- shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_DATA_FLOAT);
+ shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_TYPE_FLOAT);
shader_addline(buffer, "tmp0%s);\n", dst_mask);
}
else
@@ -4291,7 +4287,7 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins)
dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i);
if (tmp_dst && (write_mask = shader_glsl_get_write_mask(&dst, mask_char)))
shader_addline(buffer, "tmp0%s = %sBitsToFloat(", mask_char,
- dst.reg.data_type == WINED3D_DATA_INT ? "int" : "uint");
+ dst.reg.data_type == WINED3D_TYPE_INT ? "int" : "uint");
else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst, dst.reg.data_type)))
continue;
@@ -4305,7 +4301,7 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins)
if (tmp_dst)
{
- shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_DATA_FLOAT);
+ shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_TYPE_FLOAT);
shader_glsl_get_write_mask(&ins->dst[0], mask_char);
shader_addline(buffer, "tmp0%s);\n", mask_char);
}
@@ -5445,7 +5441,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
struct wined3d_string_buffer *buffer = ins->ctx->buffer;
enum wined3d_shader_resource_type resource_type;
struct wined3d_string_buffer *address;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
unsigned int resource_idx, stride;
const char *op, *resource;
DWORD coord_mask;
@@ -5461,7 +5457,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
return;
}
resource = "g";
- data_type = WINED3D_DATA_UINT;
+ data_type = WINED3D_TYPE_UINT;
coord_mask = 1;
stride = reg_maps->tgsm[resource_idx].stride;
}
@@ -5513,7 +5509,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMax";
else
op = "imageAtomicMax";
- if (data_type != WINED3D_DATA_INT)
+ if (data_type != WINED3D_TYPE_INT)
{
FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx);
return;
@@ -5525,7 +5521,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMin";
else
op = "imageAtomicMin";
- if (data_type != WINED3D_DATA_INT)
+ if (data_type != WINED3D_TYPE_INT)
{
FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx);
return;
@@ -5544,7 +5540,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMax";
else
op = "imageAtomicMax";
- if (data_type != WINED3D_DATA_UINT)
+ if (data_type != WINED3D_TYPE_UINT)
{
FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx);
return;
@@ -5556,7 +5552,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMin";
else
op = "imageAtomicMin";
- if (data_type != WINED3D_DATA_UINT)
+ if (data_type != WINED3D_TYPE_UINT)
{
FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx);
return;
@@ -5640,7 +5636,7 @@ static void shader_glsl_ld_uav(const struct wined3d_shader_instruction *ins)
const struct wined3d_shader_version *version = ®_maps->shader_version;
enum wined3d_shader_resource_type resource_type;
struct glsl_src_param image_coord_param;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
DWORD coord_mask, write_mask;
unsigned int uav_idx;
char dst_swizzle[6];
@@ -5761,7 +5757,7 @@ static void shader_glsl_store_uav(const struct wined3d_shader_instruction *ins)
const struct wined3d_shader_version *version = ®_maps->shader_version;
struct glsl_src_param image_coord_param, image_data_param;
enum wined3d_shader_resource_type resource_type;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
unsigned int uav_idx;
DWORD coord_mask;
@@ -5951,7 +5947,7 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
enum wined3d_shader_resource_type resource_type;
enum wined3d_shader_register_type reg_type;
unsigned int resource_idx, bind_idx, i;
- enum wined3d_data_type dst_data_type;
+ enum wined3d_component_type dst_data_type;
struct glsl_src_param lod_param;
BOOL supports_mipmaps;
char dst_swizzle[6];
@@ -5959,7 +5955,7 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
dst_data_type = ins->dst[0].reg.data_type;
if (ins->flags == WINED3DSI_RESINFO_UINT)
- dst_data_type = WINED3D_DATA_UINT;
+ dst_data_type = WINED3D_TYPE_UINT;
else if (ins->flags)
FIXME("Unhandled flags %#x.\n", ins->flags);
@@ -5987,7 +5983,7 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], dst_data_type);
shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle);
- if (dst_data_type == WINED3D_DATA_UINT)
+ if (dst_data_type == WINED3D_TYPE_UINT)
shader_addline(buffer, "uvec4(");
else
shader_addline(buffer, "vec4(");
@@ -6040,21 +6036,21 @@ static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins
const struct wined3d_shader_dst_param *dst = ins->dst;
const struct wined3d_shader_src_param *src = ins->src;
enum wined3d_shader_resource_type resource_type;
- enum wined3d_data_type dst_data_type;
+ enum wined3d_component_type dst_data_type;
unsigned int resource_idx, bind_idx;
char dst_swizzle[6];
DWORD write_mask;
dst_data_type = dst->reg.data_type;
if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT)
- dst_data_type = WINED3D_DATA_UINT;
+ dst_data_type = WINED3D_TYPE_UINT;
else if (ins->flags)
FIXME("Unhandled flags %#x.\n", ins->flags);
write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type);
shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle);
- if (dst_data_type == WINED3D_DATA_UINT)
+ if (dst_data_type == WINED3D_TYPE_UINT)
shader_addline(buffer, "uvec4(");
else
shader_addline(buffer, "vec4(");
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 44879f8b7c4..7c6b1243d79 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1030,6 +1030,23 @@ static HRESULT shader_scan_output_signature(struct wined3d_shader *shader)
return WINED3D_OK;
}
+static enum wined3d_component_type component_type_from_data_type(enum wined3d_data_type type)
+{
+ switch (type)
+ {
+ case WINED3D_DATA_FLOAT:
+ case WINED3D_DATA_UNORM:
+ case WINED3D_DATA_SNORM:
+ return WINED3D_TYPE_FLOAT;
+ case WINED3D_DATA_INT:
+ return WINED3D_TYPE_INT;
+ case WINED3D_DATA_UINT:
+ return WINED3D_TYPE_UINT;
+ }
+ ERR("Unexpected data type %u.\n", type);
+ return WINED3D_TYPE_FLOAT;
+}
+
/* Note that this does not count the loop register as an address register. */
static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size)
{
@@ -1128,7 +1145,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->resource_info[reg_idx].type = semantic->resource_type;
- reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type;
+ reg_maps->resource_info[reg_idx].data_type =
+ component_type_from_data_type(semantic->resource_data_type);
break;
case WINED3DSPR_UAV:
@@ -1138,7 +1156,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->uav_resource_info[reg_idx].type = semantic->resource_type;
- reg_maps->uav_resource_info[reg_idx].data_type = semantic->resource_data_type;
+ reg_maps->uav_resource_info[reg_idx].data_type =
+ component_type_from_data_type(semantic->resource_data_type);
if (ins.flags)
FIXME("Ignoring typed UAV flags %#x.\n", ins.flags);
break;
@@ -1270,7 +1289,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->resource_info[reg_idx].flags = WINED3D_VIEW_BUFFER_RAW;
}
else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_STRUCTURED)
@@ -1282,7 +1301,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->resource_info[reg_idx].flags = 0;
reg_maps->resource_info[reg_idx].stride = ins.declaration.structured_resource.byte_stride / 4;
}
@@ -1356,7 +1375,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
if (ins.flags)
FIXME("Ignoring raw UAV flags %#x.\n", ins.flags);
reg_maps->uav_resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->uav_resource_info[reg_idx].flags = WINED3D_VIEW_BUFFER_RAW;
}
else if (ins.handler_idx == WINED3DSIH_DCL_UAV_STRUCTURED)
@@ -1370,7 +1389,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
if (ins.flags)
FIXME("Ignoring structured UAV flags %#x.\n", ins.flags);
reg_maps->uav_resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->uav_resource_info[reg_idx].flags = 0;
reg_maps->uav_resource_info[reg_idx].stride = ins.declaration.structured_resource.byte_stride / 4;
}
@@ -1609,7 +1628,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
TRACE("Setting fake 2D resource for 1.x pixelshader.\n");
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
- reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT;
+ reg_maps->resource_info[reg_idx].data_type = WINED3D_TYPE_FLOAT;
shader_record_sample(reg_maps, reg_idx, reg_idx, reg_idx);
/* texbem is only valid with < 1.4 pixel shaders */
@@ -2442,13 +2461,13 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
case WINED3D_IMMCONST_SCALAR:
switch (reg->data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
shader_addline(buffer, "%.8e", *(const float *)reg->u.immconst_data);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
shader_addline(buffer, "%d", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
shader_addline(buffer, "%u", reg->u.immconst_data[0]);
break;
default:
@@ -2460,17 +2479,17 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
case WINED3D_IMMCONST_VEC4:
switch (reg->data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
shader_addline(buffer, "%.8e, %.8e, %.8e, %.8e",
*(const float *)®->u.immconst_data[0], *(const float *)®->u.immconst_data[1],
*(const float *)®->u.immconst_data[2], *(const float *)®->u.immconst_data[3]);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
shader_addline(buffer, "%d, %d, %d, %d",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
shader_addline(buffer, "%u, %u, %u, %u",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c
index 0c6bb933174..b57b67b8dcc 100644
--- a/dlls/wined3d/shader_sm1.c
+++ b/dlls/wined3d/shader_sm1.c
@@ -468,7 +468,7 @@ static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_
{
src->reg.type = ((param & WINED3D_SM1_REGISTER_TYPE_MASK) >> WINED3D_SM1_REGISTER_TYPE_SHIFT)
| ((param & WINED3D_SM1_REGISTER_TYPE_MASK2) >> WINED3D_SM1_REGISTER_TYPE_SHIFT2);
- src->reg.data_type = WINED3D_DATA_FLOAT;
+ src->reg.data_type = WINED3D_TYPE_FLOAT;
src->reg.idx[0].offset = param & WINED3D_SM1_REGISTER_NUMBER_MASK;
src->reg.idx[0].rel_addr = rel_addr;
src->reg.idx[1].offset = ~0U;
@@ -482,7 +482,7 @@ static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_
{
dst->reg.type = ((param & WINED3D_SM1_REGISTER_TYPE_MASK) >> WINED3D_SM1_REGISTER_TYPE_SHIFT)
| ((param & WINED3D_SM1_REGISTER_TYPE_MASK2) >> WINED3D_SM1_REGISTER_TYPE_SHIFT2);
- dst->reg.data_type = WINED3D_DATA_FLOAT;
+ dst->reg.data_type = WINED3D_TYPE_FLOAT;
dst->reg.idx[0].offset = param & WINED3D_SM1_REGISTER_NUMBER_MASK;
dst->reg.idx[0].rel_addr = rel_addr;
dst->reg.idx[1].offset = ~0U;
@@ -645,12 +645,12 @@ static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_se
{
semantic->resource_type = resource_type_table[resource_type];
}
- semantic->resource_data_type = WINED3D_DATA_FLOAT;
+ semantic->resource_data_type = WINED3D_TYPE_FLOAT;
shader_parse_dst_param(dst_token, NULL, &semantic->reg);
}
static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
- enum wined3d_immconst_type type, enum wined3d_data_type data_type)
+ enum wined3d_immconst_type type, enum wined3d_component_type data_type)
{
unsigned int count = type == WINED3D_IMMCONST_VEC4 ? 4 : 1;
src_param->reg.type = WINED3DSPR_IMMCONST;
@@ -761,17 +761,17 @@ static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wi
else if (ins->handler_idx == WINED3DSIH_DEF)
{
shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
- shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_FLOAT);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_TYPE_FLOAT);
}
else if (ins->handler_idx == WINED3DSIH_DEFB)
{
shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
- shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_SCALAR, WINED3D_DATA_UINT);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_SCALAR, WINED3D_TYPE_UINT);
}
else if (ins->handler_idx == WINED3DSIH_DEFI)
{
shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
- shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_INT);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_TYPE_INT);
}
else
{
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index acde7a56d1c..7508dda4e07 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -517,15 +517,15 @@ static const enum wined3d_data_type data_type_table[] =
};
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
+ enum wined3d_component_type data_type, struct wined3d_shader_src_param *src_param);
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param);
+ enum wined3d_component_type data_type, struct wined3d_shader_dst_param *dst_param);
static void shader_sm4_read_conditional_op(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &priv->src_param[0]);
ins->flags = (opcode_token & WINED3D_SM4_CONDITIONAL_NZ) ?
WINED3D_SHADER_CONDITIONAL_OP_NZ : WINED3D_SHADER_CONDITIONAL_OP_Z;
}
@@ -579,7 +579,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
uav = opcode != WINED3D_SM4_OP_DCL_RESOURCE;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.semantic.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.semantic.reg);
components = *tokens++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
@@ -589,7 +589,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
{
FIXME("Unhandled data type %#x.\n", data_type);
- ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT;
+ ins->declaration.semantic.resource_data_type = WINED3D_TYPE_FLOAT;
}
else
{
@@ -604,7 +604,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct wined3d_shader_instructio
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.src);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.src);
if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK)
ins->flags |= WINED3DSI_INDEXED_DYNAMIC;
}
@@ -616,14 +616,14 @@ static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT;
if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON)
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT,
&ins->declaration.index_range.first_register);
ins->declaration.index_range.last_register = *tokens;
}
@@ -680,14 +680,14 @@ static void shader_sm4_read_declaration_dst(struct wined3d_shader_instruction *i
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.dst);
}
static void shader_sm4_read_declaration_register_semantic(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT,
&ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@@ -697,7 +697,7 @@ static void shader_sm4_read_dcl_input_ps(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *ins,
@@ -705,7 +705,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *
struct wined3d_sm4_data *priv)
{
ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT,
&ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@@ -731,7 +731,7 @@ static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
priv->src_param[0].reg.u.fp_body_idx = *tokens++;
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &priv->src_param[0]);
}
static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins,
@@ -812,7 +812,7 @@ static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.dst);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@@ -820,7 +820,7 @@ static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT,
&ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
@@ -832,7 +832,7 @@ static void shader_sm5_read_dcl_tgsm_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.tgsm_raw.reg);
ins->declaration.tgsm_raw.byte_count = *tokens;
if (ins->declaration.tgsm_raw.byte_count % 4)
FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count);
@@ -842,7 +842,7 @@ static void shader_sm5_read_dcl_tgsm_structured(struct wined3d_shader_instructio
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT,
&ins->declaration.tgsm_structured.reg);
ins->declaration.tgsm_structured.byte_stride = *tokens++;
ins->declaration.tgsm_structured.structure_count = *tokens;
@@ -854,7 +854,7 @@ static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instru
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT,
&ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
if (ins->declaration.structured_resource.byte_stride % 4)
@@ -865,7 +865,7 @@ static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction *
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.dst);
}
static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
@@ -1196,23 +1196,23 @@ static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_sha
}
}
-static enum wined3d_data_type map_data_type(char t)
+static enum wined3d_component_type map_data_type(char t)
{
switch (t)
{
case 'f':
- return WINED3D_DATA_FLOAT;
+ return WINED3D_TYPE_FLOAT;
case 'i':
- return WINED3D_DATA_INT;
+ return WINED3D_TYPE_INT;
case 'u':
case 'O':
case 'R':
case 'S':
case 'U':
- return WINED3D_DATA_UINT;
+ return WINED3D_TYPE_UINT;
default:
ERR("Invalid data type '%c'.\n", t);
- return WINED3D_DATA_FLOAT;
+ return WINED3D_TYPE_FLOAT;
}
}
@@ -1376,7 +1376,7 @@ static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD *
reg_idx->offset = *(*ptr)++;
else
reg_idx->offset = 0;
- shader_sm4_read_src_param(priv, ptr, end, WINED3D_DATA_INT, rel_addr);
+ shader_sm4_read_src_param(priv, ptr, end, WINED3D_TYPE_INT, rel_addr);
}
else
{
@@ -1388,7 +1388,7 @@ static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD *
}
static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_register *param,
+ enum wined3d_component_type data_type, struct wined3d_shader_register *param,
enum wined3d_shader_src_modifier *modifier)
{
enum wined3d_sm4_register_type register_type;
@@ -1520,7 +1520,7 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
}
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param)
+ enum wined3d_component_type data_type, struct wined3d_shader_src_param *src_param)
{
DWORD token;
@@ -1571,7 +1571,7 @@ static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD
}
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param)
+ enum wined3d_component_type data_type, struct wined3d_shader_dst_param *dst_param)
{
enum wined3d_shader_src_modifier modifier;
DWORD token;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b65288dc415..6aa1d497df1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -933,7 +933,7 @@ struct wined3d_shader_version
struct wined3d_shader_resource_info
{
enum wined3d_shader_resource_type type;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
unsigned int flags;
unsigned int stride;
};
@@ -1071,7 +1071,7 @@ struct wined3d_shader_register_index
struct wined3d_shader_register
{
enum wined3d_shader_register_type type;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
struct wined3d_shader_register_index idx[2];
enum wined3d_immconst_type immconst_type;
union
--
2.16.4
June 20, 2018
[PATCH v2 2/5] wined3d: Get rid of unnecessary enum wined3d_data_type values.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Restore _UNORM and _SNORM for semantics / declarations.
dlls/wined3d/glsl_shader.c | 8 --------
dlls/wined3d/shader.c | 4 ----
dlls/wined3d/shader_sm4.c | 44 ++++++++++++++++++------------------------
dlls/wined3d/wined3d_private.h | 4 ----
4 files changed, 19 insertions(+), 41 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 86259ae4755..f1f3020d53d 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3093,8 +3093,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
case WINED3D_DATA_INT:
sprintf(register_name, "%#x", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
sprintf(register_name, "%#xu", reg->u.immconst_data[0]);
break;
@@ -3129,8 +3127,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
reg->u.immconst_data[0], reg->u.immconst_data[1],
@@ -3342,8 +3338,6 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
case WINED3D_DATA_INT:
string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
return;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
return;
@@ -3457,8 +3451,6 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer,
shader_addline(buffer, "%s%s = %sintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
shader_addline(buffer, "%s%s = %suintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 20d4f0773dd..44879f8b7c4 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2448,8 +2448,6 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
case WINED3D_DATA_INT:
shader_addline(buffer, "%d", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
shader_addline(buffer, "%u", reg->u.immconst_data[0]);
break;
@@ -2472,8 +2470,6 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
shader_addline(buffer, "%u, %u, %u, %u",
reg->u.immconst_data[0], reg->u.immconst_data[1],
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index b119e8feaa8..acde7a56d1c 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -565,8 +565,8 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
{
enum wined3d_sm4_resource_type resource_type;
enum wined3d_sm4_data_type data_type;
- enum wined3d_data_type reg_data_type;
DWORD components;
+ BOOL uav;
resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT;
if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table)))
@@ -578,8 +578,8 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
{
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
- reg_data_type = opcode == WINED3D_SM4_OP_DCL_RESOURCE ? WINED3D_DATA_RESOURCE : WINED3D_DATA_UAV;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], reg_data_type, &ins->declaration.semantic.reg);
+ uav = opcode != WINED3D_SM4_OP_DCL_RESOURCE;
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.semantic.reg);
components = *tokens++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
@@ -596,7 +596,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
ins->declaration.semantic.resource_data_type = data_type_table[data_type];
}
- if (reg_data_type == WINED3D_DATA_UAV)
+ if (uav)
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@@ -616,14 +616,14 @@ static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT;
if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON)
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_SAMPLER, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
&ins->declaration.index_range.first_register);
ins->declaration.index_range.last_register = *tokens;
}
@@ -731,7 +731,7 @@ static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
priv->src_param[0].reg.u.fp_body_idx = *tokens++;
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE, &priv->src_param[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
}
static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins,
@@ -812,7 +812,7 @@ static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@@ -820,7 +820,7 @@ static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
&ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
@@ -854,7 +854,7 @@ static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instru
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
&ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
if (ins->declaration.structured_resource.byte_stride % 4)
@@ -865,7 +865,7 @@ static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction *
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
}
static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
@@ -875,15 +875,13 @@ static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM5_SYNC_FLAGS_MASK) >> WINED3D_SM5_SYNC_FLAGS_SHIFT;
}
-/*
- * f -> WINED3D_DATA_FLOAT
- * i -> WINED3D_DATA_INT
- * u -> WINED3D_DATA_UINT
- * O -> WINED3D_DATA_OPAQUE
- * R -> WINED3D_DATA_RESOURCE
- * S -> WINED3D_DATA_SAMPLER
- * U -> WINED3D_DATA_UAV
- */
+/* f -> FLOAT
+ * i -> INT
+ * u -> UINT
+ * O -> OPAQUE
+ * R -> RESOURCE
+ * S -> SAMPLER
+ * U -> UAV */
static const struct wined3d_sm4_opcode_info opcode_table[] =
{
{WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "f", "ff"},
@@ -1207,15 +1205,11 @@ static enum wined3d_data_type map_data_type(char t)
case 'i':
return WINED3D_DATA_INT;
case 'u':
- return WINED3D_DATA_UINT;
case 'O':
- return WINED3D_DATA_OPAQUE;
case 'R':
- return WINED3D_DATA_RESOURCE;
case 'S':
- return WINED3D_DATA_SAMPLER;
case 'U':
- return WINED3D_DATA_UAV;
+ return WINED3D_DATA_UINT;
default:
ERR("Invalid data type '%c'.\n", t);
return WINED3D_DATA_FLOAT;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9aa70817f5d..b65288dc415 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -504,13 +504,9 @@ enum wined3d_data_type
{
WINED3D_DATA_FLOAT,
WINED3D_DATA_INT,
- WINED3D_DATA_RESOURCE,
- WINED3D_DATA_SAMPLER,
- WINED3D_DATA_UAV,
WINED3D_DATA_UINT,
WINED3D_DATA_UNORM,
WINED3D_DATA_SNORM,
- WINED3D_DATA_OPAQUE,
};
enum wined3d_immconst_type
--
2.16.4
June 20, 2018
[PATCH v2 1/5] d3dx9/tests: Add initial tests for ID3DXFont::DrawText().
by Matteo Bruni
From: Kieran Duggan <kieranduggan15(a)gmail.com>
Signed-off-by: Kieran Duggan <kieranduggan15(a)gmail.com>
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Add missing todo_wine.
dlls/d3dx9_36/tests/core.c | 84 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c
index 75d33c1e0dc..91e458bbb88 100644
--- a/dlls/d3dx9_36/tests/core.c
+++ b/dlls/d3dx9_36/tests/core.c
@@ -305,23 +305,28 @@ static void test_ID3DXSprite(IDirect3DDevice9 *device)
static void test_ID3DXFont(IDirect3DDevice9 *device)
{
- D3DXFONT_DESCA desc;
- ID3DXFont *font;
- HRESULT hr;
- int ref;
- int i;
- static const struct {
- INT font_height;
- UINT expected_size;
- DWORD expected_levels;
- } texture_tests[] = {
+ static const WCHAR testW[] = {'t','e','s','t',0};
+ static const struct
+ {
+ int font_height;
+ unsigned int expected_size;
+ unsigned int expected_levels;
+ }
+ tests[] =
+ {
{ 6, 128, 4 },
{ 8, 128, 4 },
{ 10, 256, 5 },
{ 12, 256, 5 },
- { 72, 256, 8 }
+ { 72, 256, 8 },
};
-
+ const unsigned int size = ARRAY_SIZE(testW);
+ D3DXFONT_DESCA desc;
+ ID3DXSprite *sprite;
+ int ref, i, height;
+ ID3DXFont *font;
+ HRESULT hr;
+ RECT rect;
/* D3DXCreateFont */
ref = get_ref((IUnknown*)device);
@@ -463,8 +468,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
/* ID3DXFont_PreloadText */
hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
if(SUCCEEDED(hr)) {
- const WCHAR testW[] = {'t','e','s','t',0};
-
todo_wine {
hr = ID3DXFont_PreloadTextA(font, NULL, -1);
ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
@@ -552,7 +555,8 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
check_release((IUnknown*)font, 0);
} else skip("Failed to create a ID3DXFont object\n");
- for(i = 0; i < ARRAY_SIZE(texture_tests); i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
+ {
HDC hdc;
DWORD ret;
HRESULT hr;
@@ -560,7 +564,8 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
char c = 'a';
IDirect3DTexture9 *texture;
- hr = D3DXCreateFontA(device, texture_tests[i].font_height, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ hr = D3DXCreateFontA(device, tests[i].font_height, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
if(FAILED(hr)) {
skip("Failed to create a ID3DXFont object\n");
continue;
@@ -578,17 +583,58 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
D3DSURFACE_DESC desc;
levels = IDirect3DTexture9_GetLevelCount(texture);
- ok(levels == texture_tests[i].expected_levels, "Got levels %u, expected %u\n", levels, texture_tests[i].expected_levels);
+ ok(levels == tests[i].expected_levels, "Got levels %u, expected %u\n",
+ levels, tests[i].expected_levels);
hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc failed\n");
ok(desc.Format == D3DFMT_A8R8G8B8, "Got format %#x, expected %#x\n", desc.Format, D3DFMT_A8R8G8B8);
ok(desc.Usage == 0, "Got usage %#x, expected %#x\n", desc.Usage, 0);
- ok(desc.Width == texture_tests[i].expected_size, "Got width %u, expected %u\n", desc.Width, texture_tests[i].expected_size);
- ok(desc.Height == texture_tests[i].expected_size, "Got height %u, expected %u\n", desc.Height, texture_tests[i].expected_size);
+ ok(desc.Width == tests[i].expected_size, "Got width %u, expected %u\n",
+ desc.Width, tests[i].expected_size);
+ ok(desc.Height == tests[i].expected_size, "Got height %u, expected %u\n",
+ desc.Height, tests[i].expected_size);
ok(desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected %u\n", desc.Pool, D3DPOOL_MANAGED);
IDirect3DTexture9_Release(texture);
}
+
+ /* ID3DXFontImpl_DrawText */
+ D3DXCreateSprite(device, &sprite);
+ SetRect(&rect, 0, 0, 640, 480);
+
+ IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
+
+ IDirect3DDevice9_BeginScene(device);
+ hr = ID3DXSprite_Begin(sprite, D3DXSPRITE_ALPHABLEND);
+ ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ todo_wine
+ {
+ height = ID3DXFont_DrawTextW(font, sprite, testW, -1, &rect, DT_TOP, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_TOP, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_RIGHT, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_NOCLIP,
+ 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ }
+
+ SetRect(&rect, 0, 0, 0, 0);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect,
+ DT_LEFT | DT_CALCRECT, 0xffffffff);
+ todo_wine ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ ok(!rect.left, "Got unexpected rect left %d.\n", rect.left);
+ ok(!rect.top, "Got unexpected rect top %d.\n", rect.top);
+ todo_wine ok(rect.right, "Got unexpected rect right %d.\n", rect.right);
+ todo_wine ok(rect.bottom == tests[i].font_height, "Got unexpected rect bottom %d.\n", rect.bottom);
+
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+ IDirect3DDevice9_EndScene(device);
+ ID3DXSprite_Release(sprite);
+
ID3DXFont_Release(font);
}
}
--
2.16.4
June 20, 2018
[PATCH resend] winedbg: Suppress all message boxes if ShowCrashDialog is disabled.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
The only message box shown by this function is the aforementioned
'failed to attach to process' error, but in general the user probably
doesn't want any windows to be shown if ShowCrashDialog is disabled.
programs/winedbg/crashdlg.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/programs/winedbg/crashdlg.c b/programs/winedbg/crashdlg.c
index 5c913ff..a925378 100644
--- a/programs/winedbg/crashdlg.c
+++ b/programs/winedbg/crashdlg.c
@@ -34,13 +34,18 @@
static char *crash_log;
-int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType)
+int msgbox_res_id(HWND hwnd, UINT textid, UINT captionid, UINT type)
{
- WCHAR caption[256];
- WCHAR text[256];
- LoadStringW(GetModuleHandleW(NULL), captionId, caption, ARRAY_SIZE(caption));
- LoadStringW(GetModuleHandleW(NULL), textId, text, ARRAY_SIZE(text));
- return MessageBoxW(hwnd, text, caption, uType);
+ if (DBG_IVAR(ShowCrashDialog))
+ {
+ WCHAR caption[256];
+ WCHAR text[256];
+ LoadStringW(GetModuleHandleW(NULL), captionid, caption, ARRAY_SIZE(caption));
+ LoadStringW(GetModuleHandleW(NULL), textid, text, ARRAY_SIZE(text));
+ return MessageBoxW(hwnd, text, caption, type);
+ }
+
+ return IDCANCEL;
}
static WCHAR *get_program_name(HANDLE hProcess)
--
2.7.4
June 20, 2018
[PATCH] wininet/tests: Use the correct array size in a notification_data test
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/wininet/tests/http.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 72121d8b77..0524ddf3fd 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -6558,7 +6558,7 @@ static const struct notification_data notification_data[] = {
},
{
async_send_request_ex_test2,
- sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
+ ARRAY_SIZE(async_send_request_ex_test2),
"POST",
"test.winehq.org",
"tests/post.php"
--
2.14.4
June 20, 2018
[PATCH 2/2] msvcrt/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msvcrt/tests/cpp.c | 6 +++---
dlls/msvcrt/tests/dir.c | 16 ++++++++--------
dlls/msvcrt/tests/file.c | 23 +++++++++++-----------
dlls/msvcrt/tests/locale.c | 6 +++---
dlls/msvcrt/tests/misc.c | 4 ++--
dlls/msvcrt/tests/printf.c | 4 ++--
dlls/msvcrt/tests/string.c | 48 +++++++++++++++++++++++-----------------------
7 files changed, 53 insertions(+), 54 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c
index cf5e4c7d60..07b49ae755 100644
--- a/dlls/msvcrt/tests/cpp.c
+++ b/dlls/msvcrt/tests/cpp.c
@@ -1108,8 +1108,8 @@ static void test_demangle_datatype(void)
{ "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE},
/* { "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$011@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$011@@@",FALSE}, */
};
- int i, num_test = (sizeof(demangle)/sizeof(struct _demangle));
-
+ int i, num_test = ARRAY_SIZE(demangle);
+
for (i = 0; i < num_test; i++)
{
name = p__unDName(0, demangle[i].mangled, 0, pmalloc, pfree, 0x2800);
@@ -1326,7 +1326,7 @@ static void test_demangle(void)
/* 130 */ {"??_E?$TStrArray@$$BY0BAA(a)D$0BA@@@UAEPAXI(a)Z",
"public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"},
};
- int i, num_test = (sizeof(test)/sizeof(test[0]));
+ int i, num_test = ARRAY_SIZE(test);
char* name;
for (i = 0; i < num_test; i++)
diff --git a/dlls/msvcrt/tests/dir.c b/dlls/msvcrt/tests/dir.c
index a29d32b9d3..210cf3983c 100644
--- a/dlls/msvcrt/tests/dir.c
+++ b/dlls/msvcrt/tests/dir.c
@@ -97,7 +97,7 @@ static void test_makepath(void)
unsigned int i, n;
- for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); ++i)
+ for (i = 0; i < ARRAY_SIZE(makepath_cases); ++i)
{
const makepath_case* p = &makepath_cases[i];
@@ -253,7 +253,7 @@ static void test_makepath_s(void)
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
/* Test with the normal _makepath cases. */
- for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(makepath_cases); i++)
{
const makepath_case *p = makepath_cases + i;
@@ -296,7 +296,7 @@ static void test_makepath_s(void)
}
/* Try insufficient length cases. */
- for (i = 0; i < sizeof(makepath_s_cases)/sizeof(makepath_s_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(makepath_s_cases); i++)
{
const makepath_s_case *p = makepath_s_cases + i;
@@ -457,12 +457,12 @@ static void test_searchenv(void)
ok(path_len, "GetTempPath failed\n");
memcpy(path, tmppath, path_len);
- for(i=0; i<sizeof(dirs)/sizeof(*dirs); i++) {
+ for (i=0; i<ARRAY_SIZE(dirs); i++) {
strcpy(path+path_len, dirs[i]);
ok(!mkdir(path), "mkdir failed (dir = %s)\n", path);
}
- for(i=0; i<sizeof(files)/sizeof(*files); i++) {
+ for (i=0; i<ARRAY_SIZE(files); i++) {
strcpy(path+path_len, files[i]);
tmp_file = fopen(path, "wb");
ok(tmp_file != NULL, "fopen failed (file = %s)\n", path);
@@ -471,7 +471,7 @@ static void test_searchenv(void)
strcpy(env1, "TEST_PATH=");
strcpy(env2, "TEST_PATH=;");
- for(i=1; i<sizeof(dirs)/sizeof(*dirs); i++) {
+ for (i=1; i<ARRAY_SIZE(dirs); i++) {
strcat(env1, tmppath);
strcat(env1, dirs[i]);
strcat(env1, ";");
@@ -599,12 +599,12 @@ static void test_searchenv(void)
putenv("TEST_PATH=");
- for(i=sizeof(files)/sizeof(*files)-1; i>=0; i--) {
+ for (i=ARRAY_SIZE(files)-1; i>=0; i--) {
strcpy(path+path_len, files[i]);
ok(!remove(path), "remove failed (file = %s)\n", path);
}
- for(i=sizeof(dirs)/sizeof(*dirs)-1; i>=0; i--) {
+ for (i=ARRAY_SIZE(dirs)-1; i>=0; i--) {
strcpy(path+path_len, dirs[i]);
ok(!rmdir(path), "rmdir failed (dir = %s)\n", path);
}
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index 136ee1563e..fe62d5c385 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -144,7 +144,7 @@ static void test_fileops( void )
write (fd, outbuffer, sizeof (outbuffer));
close (fd);
- for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
+ for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++)
{
fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
file = fdopen (fd, "rb");
@@ -195,13 +195,13 @@ static void test_fileops( void )
}
fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
file = fdopen (fd, "rt"); /* open in TEXT mode */
- ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
- ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
+ ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) !=0,"fgetws failed unexpected\n");
+ ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) ==0,"fgetws didn't signal EOF\n");
ok(feof(file) !=0,"feof doesn't signal EOF\n");
rewind(file);
ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
- ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
+ ok(fgetws(wbuffer,ARRAY_SIZE(outbuffer),file) !=0,"fgets failed unexpected\n");
ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
fclose (file);
@@ -624,7 +624,7 @@ static void test_flsbuf( void )
static const int bufmodes[] = {_IOFBF,_IONBF};
tempf=_tempnam(".","wne");
- for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
+ for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++)
{
tempfh = fopen(tempf,"wb");
setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
@@ -878,8 +878,7 @@ static void test_fgetwc_locale(const char* text, const char* locale, int codepag
{
/* mbstowcs rejects invalid multibyte sequence,
so we use MultiByteToWideChar here. */
- ret = MultiByteToWideChar(codepage, 0, text, -1,
- wtextW, sizeof(wtextW)/sizeof(wtextW[0]));
+ ret = MultiByteToWideChar(codepage, 0, text, -1, wtextW, ARRAY_SIZE(wtextW));
ok(ret > 0, "MultiByteToWideChar failed\n");
}
else
@@ -910,7 +909,7 @@ static void test_fgetwc_locale(const char* text, const char* locale, int codepag
tempfh = fopen(tempfile, "rb");
ok(tempfh != NULL, "can't open tempfile\n");
- for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(wchar_text); i++)
{
ch = fgetwc(tempfh);
ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i);
@@ -946,7 +945,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "rt,ccs=unicode");
ok(tempfh != NULL, "can't open tempfile\n");
- for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
+ for (i = 1; i < ARRAY_SIZE(wchar_text); i++)
{
ch = fgetwc(tempfh);
ok(ch == wchar_text[i],
@@ -958,7 +957,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "wb");
ok(tempfh != NULL, "can't open tempfile\n");
- ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]),
+ ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, ARRAY_SIZE(wchar_text),
utf8_text, sizeof(utf8_text), NULL, NULL);
ok(ret > 0, "utf-8 conversion failed\n");
fwrite(utf8_text, sizeof(char), ret, tempfh);
@@ -966,7 +965,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "rt, ccs=UTF-8");
ok(tempfh != NULL, "can't open tempfile\n");
- for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
+ for (i = 1; i < ARRAY_SIZE(wchar_text); i++)
{
ch = fgetwc(tempfh);
ok(ch == wchar_text[i],
@@ -2659,5 +2658,5 @@ START_TEST(file)
/* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
* file contains lines in the correct order
*/
- WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);
+ WaitForMultipleObjects(ARRAY_SIZE(proc_handles), proc_handles, TRUE, 5000);
}
diff --git a/dlls/msvcrt/tests/locale.c b/dlls/msvcrt/tests/locale.c
index 024afc15b3..ff777599aa 100644
--- a/dlls/msvcrt/tests/locale.c
+++ b/dlls/msvcrt/tests/locale.c
@@ -643,7 +643,7 @@ static void test_crtGetStringTypeW(void)
return;
}
- for(i=0; i<sizeof(str)/sizeof(*str); i++) {
+ for(i=0; i<ARRAY_SIZE(str); i++) {
ret_crt = p__crtGetStringTypeW(0, CT_CTYPE1, str[i], 1, &out_crt);
ret = GetStringTypeW(CT_CTYPE1, str[i], 1, &out);
ok(ret == ret_crt, "%d) ret_crt = %d\n", i, (int)ret_crt);
@@ -708,7 +708,7 @@ static void test__Gettnames(void)
else
ok(size==0x164 || broken(size==0xb8), "structure size: %x\n", size);
- for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(time_data); i++)
{
size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT),
time_data[i], buf, sizeof(buf));
@@ -722,7 +722,7 @@ static void test__Gettnames(void)
return;
ret = _Gettnames();
- for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(time_data); i++)
{
size = GetLocaleInfoA(MAKELCID(LANG_GERMAN, SORT_DEFAULT),
time_data[i], buf, sizeof(buf));
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index 017ae7758a..c170d23225 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -164,7 +164,7 @@ static void test_I10_OUTPUT(void)
if (j != 12)
trace("sizeof(long double) = %d on this machine\n", j);
- for(i=0; i<sizeof(I10_OUTPUT_tests)/sizeof(I10_OUTPUT_test); i++) {
+ for(i=0; i<ARRAY_SIZE(I10_OUTPUT_tests); i++) {
memset(out.str, '#', sizeof(out.str));
if (sizeof(long double) == 12)
@@ -621,7 +621,7 @@ static void test__lfind_s(void)
}
key = 1234;
- num = sizeof(tests)/sizeof(tests[0]);
+ num = ARRAY_SIZE(tests);
errno = 0xdeadbeef;
found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL);
diff --git a/dlls/msvcrt/tests/printf.c b/dlls/msvcrt/tests/printf.c
index 64658ce25f..80180ff8b2 100644
--- a/dlls/msvcrt/tests/printf.c
+++ b/dlls/msvcrt/tests/printf.c
@@ -841,7 +841,7 @@ static void test_snprintf (void)
const int bufsiz = sizeof buffer;
unsigned int i;
- for (i = 0; i < sizeof tests / sizeof tests[0]; i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
const char *fmt = tests[i].format;
const int expect = tests[i].expected;
const int n = _snprintf (buffer, bufsiz, fmt);
@@ -1215,7 +1215,7 @@ static void test_vsnwprintf(void)
wchar_t str[32];
char buf[32];
- ret = _vsnwprintf_wrapper( str, sizeof(str)/sizeof(str[0]), format, one, two, three );
+ ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), format, one, two, three );
ok( ret == 11, "got %d expected 11\n", ret );
WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL );
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 07458d4474..744035a1b8 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -1014,7 +1014,7 @@ static void test_wcscpy_s(void)
return;
}
- ret = p_wcsncpy_s(NULL, 18, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(NULL, 18, szLongText, ARRAY_SIZE(szLongText));
ok(ret == EINVAL, "p_wcsncpy_s expect EINVAL got %d\n", ret);
szDest[0] = 'A';
@@ -1028,16 +1028,16 @@ static void test_wcscpy_s(void)
ok(szDest[0] == 0, "szDest[0] not 0\n");
szDest[0] = 'A';
- ret = p_wcsncpy_s(szDest, 0, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(szDest, 0, szLongText, ARRAY_SIZE(szLongText));
ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n");
- ret = p_wcsncpy_s(szDest, 18, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(szDest, 18, szLongText, ARRAY_SIZE(szLongText));
ok(ret == 0, "expected 0 got %d\n", ret);
ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n");
szDest[0] = 'A';
- ret = p_wcsncpy_s(szDestShort, 8, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(szDestShort, 8, szLongText, ARRAY_SIZE(szLongText));
ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
@@ -1065,7 +1065,7 @@ static void test__wcsupr_s(void)
static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O',
'W', 'E', 'R', 'U', 'P', 'P', 'E',
'R', 0};
- WCHAR testBuffer[2*sizeof(mixedString)/sizeof(WCHAR)];
+ WCHAR testBuffer[2*ARRAY_SIZE(mixedString)];
int ret;
if (!p_wcsupr_s)
@@ -1082,7 +1082,7 @@ static void test__wcsupr_s(void)
/* Test NULL input string and valid size. */
errno = EBADF;
- ret = p_wcsupr_s(NULL, sizeof(testBuffer)/sizeof(WCHAR));
+ ret = p_wcsupr_s(NULL, ARRAY_SIZE(testBuffer));
ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
@@ -1126,21 +1126,21 @@ static void test__wcsupr_s(void)
/* Test normal string uppercasing. */
wcscpy(testBuffer, mixedString);
- ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR));
+ ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString));
ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
/* Test uppercasing with a shorter buffer size count. */
wcscpy(testBuffer, mixedString);
errno = EBADF;
- ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR) - 1);
+ ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString) - 1);
ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
/* Test uppercasing with a longer buffer size count. */
wcscpy(testBuffer, mixedString);
- ret = p_wcsupr_s(testBuffer, sizeof(testBuffer)/sizeof(WCHAR));
+ ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(testBuffer));
ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
}
@@ -1152,7 +1152,7 @@ static void test__wcslwr_s(void)
static const WCHAR expectedString[] = {'m', 'i', 'x', 'e', 'd', 'l', 'o',
'w', 'e', 'r', 'u', 'p', 'p', 'e',
'r', 0};
- WCHAR buffer[2*sizeof(mixedString)/sizeof(WCHAR)];
+ WCHAR buffer[2*ARRAY_SIZE(mixedString)];
int ret;
if (!p_wcslwr_s)
@@ -1169,7 +1169,7 @@ static void test__wcslwr_s(void)
/* Test NULL input string and valid size. */
errno = EBADF;
- ret = p_wcslwr_s(NULL, sizeof(buffer)/sizeof(buffer[0]));
+ ret = p_wcslwr_s(NULL, ARRAY_SIZE(buffer));
ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
@@ -1213,21 +1213,21 @@ static void test__wcslwr_s(void)
/* Test normal string uppercasing. */
wcscpy(buffer, mixedString);
- ret = p_wcslwr_s(buffer, sizeof(mixedString)/sizeof(WCHAR));
+ ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString));
ok(ret == 0, "expected 0, got %d\n", ret);
ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
/* Test uppercasing with a shorter buffer size count. */
wcscpy(buffer, mixedString);
errno = EBADF;
- ret = p_wcslwr_s(buffer, sizeof(mixedString)/sizeof(WCHAR) - 1);
+ ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString) - 1);
ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno);
ok(buffer[0] == '\0', "expected empty string\n");
/* Test uppercasing with a longer buffer size count. */
wcscpy(buffer, mixedString);
- ret = p_wcslwr_s(buffer, sizeof(buffer)/sizeof(WCHAR));
+ ret = p_wcslwr_s(buffer, ARRAY_SIZE(buffer));
ok(ret == 0, "expected 0, got %d\n", ret);
ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
}
@@ -1243,7 +1243,7 @@ static void test_mbcjisjms(void)
unsigned int i, j;
int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cp); i++)
{
_setmbcp(cp[i]);
for (j = 0; jisjms[j][0] != 0; j++)
@@ -1271,7 +1271,7 @@ static void test_mbcjmsjis(void)
unsigned int i, j;
int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cp); i++)
{
_setmbcp(cp[i]);
for (j = 0; jmsjis[j][0] != 0; j++)
@@ -1298,7 +1298,7 @@ static void test_mbctohira(void)
unsigned int prev_cp = _getmbcp();
_setmbcp(_MB_CP_SBCS);
- for (i = 0; i < sizeof(mbchira_932)/sizeof(mbchira_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbchira_932); i++)
{
int ret, exp = mbchira_932[i][0];
ret = _mbctohira(mbchira_932[i][0]);
@@ -1306,7 +1306,7 @@ static void test_mbctohira(void)
}
_setmbcp(932);
- for (i = 0; i < sizeof(mbchira_932)/sizeof(mbchira_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbchira_932); i++)
{
unsigned int ret, exp;
ret = _mbctohira(mbchira_932[i][0]);
@@ -1327,7 +1327,7 @@ static void test_mbctokata(void)
unsigned int prev_cp = _getmbcp();
_setmbcp(_MB_CP_SBCS);
- for (i = 0; i < sizeof(mbckata_932)/sizeof(mbckata_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbckata_932); i++)
{
int ret, exp = mbckata_932[i][0];
ret = _mbctokata(mbckata_932[i][0]);
@@ -1335,7 +1335,7 @@ static void test_mbctokata(void)
}
_setmbcp(932);
- for (i = 0; i < sizeof(mbckata_932)/sizeof(mbckata_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbckata_932); i++)
{
unsigned int ret, exp;
ret = _mbctokata(mbckata_932[i][0]);
@@ -1356,7 +1356,7 @@ static void test_mbbtombc(void)
int i, j;
int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cp); i++)
{
_setmbcp(cp[i]);
for (j = 0; mbbmbc[j][0] != 0; j++)
@@ -1409,13 +1409,13 @@ static void test_ismbckata(void) {
unsigned int i;
_setmbcp(_MB_CP_SBCS);
- for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
ret = _ismbckata(tests[i].c);
ok(!ret, "expected 0, got %d for %04x\n", ret, tests[i].c);
}
_setmbcp(932);
- for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
ret = _ismbckata(tests[i].c);
ok(!!ret == tests[i].exp, "expected %d, got %d for %04x\n",
tests[i].exp, !!ret, tests[i].c);
@@ -2993,7 +2993,7 @@ static void test__wcstoi64(void)
ok(ures == 071, "ures != 071\n");
/* Test various unicode digits */
- for (i = 0; i < sizeof(zeros) / sizeof(zeros[0]); ++i) {
+ for (i = 0; i < ARRAY_SIZE(zeros); ++i) {
WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0};
res = p_wcstoi64(tmp, NULL, 0);
ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res);
--
2.14.4
June 20, 2018
[PATCH 1/2] msvcrt: Rename a macro to ARRAY_SIZE()
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msvcrt/tests/string.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 2e963dc8ad..07458d4474 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -607,8 +607,6 @@ static void test_strcpy_s(void)
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
-#define NUMELMS(array) (sizeof(array)/sizeof((array)[0]))
-
#define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \
ok(dst[0] == b0 && dst[1] == b1 && dst[2] == b2 && dst[3] == b3 && \
dst[4] == b4 && dst[5] == b5 && dst[6] == b6 && dst[7] == b7, \
@@ -628,14 +626,14 @@ static void test_memcpy_s(void)
/* Normal */
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == 0, "Copying a buffer into a big enough destination returned %d, expected 0\n", ret);
okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
/* Vary source size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, NUMELMS(dest), big, NUMELMS(big));
+ ret = p_memcpy_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big));
ok(ret == ERANGE, "Copying a big buffer to a small destination returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -643,7 +641,7 @@ static void test_memcpy_s(void)
/* Replace source with NULL */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Copying a NULL source buffer returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -651,21 +649,21 @@ static void test_memcpy_s(void)
/* Vary dest size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, 0, tiny, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, 0, tiny, ARRAY_SIZE(tiny));
ok(ret == ERANGE, "Copying into a destination of size 0 returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
/* Replace dest with NULL */
errno = 0xdeadbeef;
- ret = p_memcpy_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memcpy_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Copying a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
/* Combinations */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, 0, NULL, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, 0, NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Copying a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
@@ -684,20 +682,20 @@ static void test_memmove_s(void)
/* Normal */
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memmove_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == 0, "Moving a buffer into a big enough destination returned %d, expected 0\n", ret);
okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
/* Overlapping */
memcpy(dest, big, sizeof(dest));
- ret = p_memmove_s(dest+1, NUMELMS(dest)-1, dest, NUMELMS(dest)-1);
+ ret = p_memmove_s(dest+1, ARRAY_SIZE(dest)-1, dest, ARRAY_SIZE(dest)-1);
ok(ret == 0, "Moving a buffer up one char returned %d, expected 0\n", ret);
okchars(dest, big[0], big[0], big[1], big[2], big[3], big[4], big[5], big[6]);
/* Vary source size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, NUMELMS(dest), big, NUMELMS(big));
+ ret = p_memmove_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big));
ok(ret == ERANGE, "Moving a big buffer to a small destination returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
@@ -705,7 +703,7 @@ static void test_memmove_s(void)
/* Replace source with NULL */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny));
+ ret = p_memmove_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Moving a NULL source buffer returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
@@ -713,21 +711,21 @@ static void test_memmove_s(void)
/* Vary dest size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, 0, tiny, NUMELMS(tiny));
+ ret = p_memmove_s(dest, 0, tiny, ARRAY_SIZE(tiny));
ok(ret == ERANGE, "Moving into a destination of size 0 returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
/* Replace dest with NULL */
errno = 0xdeadbeef;
- ret = p_memmove_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memmove_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Moving a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
/* Combinations */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, 0, NULL, NUMELMS(tiny));
+ ret = p_memmove_s(dest, 0, NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Moving a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
--
2.14.4
June 20, 2018
Re: [PATCH] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
> It looks like it's enough to merge conditions to avoid
such repetition.
You're right, it looks a bit awkward. How about the
new version?
Regards,
Fabian Maurer
June 20, 2018
[PATCH v2] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
The menu must be release on all code-paths,
else the underlying lock will never be released.
Fixes bug 45355.
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/user32/menu.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 8c541cc4f91..570c6992cc9 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -3751,9 +3751,11 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
/* Get the parent menu to access*/
parentMenu = grab_menu_ptr(menu->hSysMenuOwner);
- release_menu_ptr(menu);
if (!parentMenu)
+ {
+ release_menu_ptr(menu);
return (UINT)-1;
+ }
hwnd = parentMenu->hWnd;
release_menu_ptr(parentMenu);
@@ -3764,8 +3766,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
}
- else
- release_menu_ptr(menu);
+ release_menu_ptr(menu);
return oldflags;
}
--
2.17.1
June 20, 2018
Re: [PATCH] user32: Always release menu item in EnableMenuItem
by Nikolay Sivov
On 6/20/2018 11:46 PM, Fabian Maurer wrote:
> The menu must be release on all code-paths,
> else the underlying lock will never be released.
>
> Fixes bug 45355.
>
> Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
> ---
> dlls/user32/menu.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
> index 8c541cc4f91..0b1133bbc41 100644
> --- a/dlls/user32/menu.c
> +++ b/dlls/user32/menu.c
> @@ -590,6 +590,7 @@ static POPUPMENU *find_menu_item(HMENU hmenu, UINT id, UINT flags, UINT *pos)
> POPUPMENU *menu;
>
> menu = grab_menu_ptr(hmenu);
> +
> if (!menu)
> return NULL;
>
> @@ -3763,6 +3764,8 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
> rc.bottom = 0;
> RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
> }
> + else
> + release_menu_ptr(menu);
> }
> else
> release_menu_ptr(menu);
>
It looks like it's enough to merge conditions to avoid such repetition.
June 20, 2018
Re: [PATCH v7 4/8] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Alexandre Julliard
Alex Henrie <alexhenrie24(a)gmail.com> writes:
> The helper function doesn't need to support more than one buffer size,
> so passing the buffer size is redundant.
>
> I'd want to hear at least one more Wine developer's opinion before
> making a change.
It's indeed ugly to make that sort of assumption in the helper
function. Also you could return the resulting length instead of having
an out variable.
--
Alexandre Julliard
julliard(a)winehq.org
June 20, 2018
[PATCH] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
The menu must be release on all code-paths,
else the underlying lock will never be released.
Fixes bug 45355.
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/user32/menu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 8c541cc4f91..0b1133bbc41 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -590,6 +590,7 @@ static POPUPMENU *find_menu_item(HMENU hmenu, UINT id, UINT flags, UINT *pos)
POPUPMENU *menu;
menu = grab_menu_ptr(hmenu);
+
if (!menu)
return NULL;
@@ -3763,6 +3764,8 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
rc.bottom = 0;
RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
+ else
+ release_menu_ptr(menu);
}
else
release_menu_ptr(menu);
--
2.17.1
June 20, 2018
Re: [PATCH v3 2/2] gdiplus: Avoid calling GdipFillPath() with an empty path.
by Vincent Povirk
Signed-off-by: Vincent Povirk <vincent(a)codeweavers.com>
June 20, 2018
Re: [PATCH v3 1/2] gdiplus: Report error for brush_fill_path().
by Vincent Povirk
Signed-off-by: Vincent Povirk <vincent(a)codeweavers.com>
June 20, 2018
[PATCH 5/5] webservices: Send incremental string table updates with messages in the same session.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/channel.c | 31 +++++++++++++++++--------------
dlls/webservices/string.c | 18 +++++++++++++++++-
dlls/webservices/webservices_private.h | 3 +++
dlls/webservices/writer.c | 19 +++++++++++++++++++
4 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 79d431f279..5963faf00d 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -1009,22 +1009,26 @@ static inline ULONG size_length( ULONG size )
return 5;
}
-static ULONG string_table_size( const WS_XML_DICTIONARY *dict )
+static ULONG string_table_size( const struct dictionary *dict )
{
ULONG i, size = 0;
- for (i = 0; i < dict->stringCount; i++)
- size += size_length( dict->strings[i].length ) + dict->strings[i].length;
+ for (i = 0; i < dict->dict.stringCount; i++)
+ {
+ if (dict->sequence[i] == dict->current_sequence)
+ size += size_length( dict->dict.strings[i].length ) + dict->dict.strings[i].length;
+ }
return size;
}
-static HRESULT send_string_table( SOCKET socket, const WS_XML_DICTIONARY *dict )
+static HRESULT send_string_table( SOCKET socket, const struct dictionary *dict )
{
ULONG i;
HRESULT hr;
- for (i = 0; i < dict->stringCount; i++)
+ for (i = 0; i < dict->dict.stringCount; i++)
{
- if ((hr = send_size( socket, dict->strings[i].length )) != S_OK) return hr;
- if ((hr = send_bytes( socket, dict->strings[i].bytes, dict->strings[i].length )) != S_OK) return hr;
+ if (dict->sequence[i] != dict->current_sequence) continue;
+ if ((hr = send_size( socket, dict->dict.strings[i].length )) != S_OK) return hr;
+ if ((hr = send_bytes( socket, dict->dict.strings[i].bytes, dict->dict.strings[i].length )) != S_OK) return hr;
}
return S_OK;
}
@@ -1154,13 +1158,13 @@ static HRESULT receive_preamble_ack( struct channel *channel )
static HRESULT send_sized_envelope( struct channel *channel, BYTE *data, ULONG len )
{
- ULONG table_size = string_table_size( &channel->dict_send.dict );
+ ULONG table_size = string_table_size( &channel->dict_send );
HRESULT hr;
if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_SIZED_ENVELOPE )) != S_OK) return hr;
if ((hr = send_size( channel->u.tcp.socket, size_length(table_size) + table_size + len )) != S_OK) return hr;
if ((hr = send_size( channel->u.tcp.socket, table_size )) != S_OK) return hr;
- if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send.dict )) != S_OK) return hr;
+ if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send )) != S_OK) return hr;
return send_bytes( channel->u.tcp.socket, data, len );
}
@@ -1285,11 +1289,8 @@ static HRESULT init_writer( struct channel *channel )
return WsSetOutput( channel->writer, &text.encoding, &buf.output, NULL, 0, NULL );
case WS_ENCODING_XML_BINARY_SESSION_1:
- clear_dict( &channel->dict_send );
- bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
- bin.dynamicStringCallback = dict_cb;
- bin.dynamicStringCallbackState = &channel->dict_send;
- return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
+ bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
+ /* fall through */
case WS_ENCODING_XML_BINARY_1:
return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
@@ -1307,6 +1308,8 @@ static HRESULT write_message( struct channel *channel, WS_MESSAGE *msg, const WS
if ((hr = writer_set_lookup( channel->writer, TRUE )) != S_OK) return hr;
if ((hr = WsWriteEnvelopeStart( msg, channel->writer, NULL, NULL, NULL )) != S_OK) return hr;
if ((hr = writer_set_lookup( channel->writer, FALSE )) != S_OK) return hr;
+ channel->dict_send.current_sequence++;
+ if ((hr = writer_set_dict_callback( channel->writer, dict_cb, &channel->dict_send )) != S_OK) return hr;
if ((hr = WsWriteBody( msg, desc, option, body, size, NULL )) != S_OK) return hr;
return WsWriteEnvelopeEnd( msg, NULL );
}
diff --git a/dlls/webservices/string.c b/dlls/webservices/string.c
index 18c55e3833..0bb77df946 100644
--- a/dlls/webservices/string.c
+++ b/dlls/webservices/string.c
@@ -91,7 +91,7 @@ int find_string( const struct dictionary *dict, const unsigned char *data, ULONG
static HRESULT grow_dict( struct dictionary *dict, ULONG size )
{
WS_XML_STRING *tmp;
- ULONG new_size, *tmp_sorted;
+ ULONG new_size, *tmp_sorted, *tmp_sequence;
assert( !dict->dict.isConst );
if (dict->size >= dict->dict.stringCount + size) return S_OK;
@@ -107,6 +107,14 @@ static HRESULT grow_dict( struct dictionary *dict, ULONG size )
dict->dict.strings = NULL;
return E_OUTOFMEMORY;
}
+ if (!(dict->sequence = heap_alloc( new_size * sizeof(*dict->sequence) )))
+ {
+ heap_free( dict->dict.strings );
+ dict->dict.strings = NULL;
+ heap_free( dict->sorted );
+ dict->sorted = NULL;
+ return E_OUTOFMEMORY;
+ }
dict->size = new_size;
return S_OK;
}
@@ -116,6 +124,8 @@ static HRESULT grow_dict( struct dictionary *dict, ULONG size )
dict->dict.strings = tmp;
if (!(tmp_sorted = heap_realloc( dict->sorted, new_size * sizeof(*tmp_sorted) ))) return E_OUTOFMEMORY;
dict->sorted = tmp_sorted;
+ if (!(tmp_sequence = heap_realloc( dict->sequence, new_size * sizeof(*tmp_sequence) ))) return E_OUTOFMEMORY;
+ dict->sequence = tmp_sequence;
dict->size = new_size;
return S_OK;
@@ -131,6 +141,9 @@ void clear_dict( struct dictionary *dict )
dict->dict.stringCount = 0;
heap_free( dict->sorted );
dict->sorted = NULL;
+ heap_free( dict->sequence );
+ dict->sequence = NULL;
+ dict->current_sequence = 0;
dict->size = 0;
}
@@ -149,6 +162,9 @@ HRESULT insert_string( struct dictionary *dict, unsigned char *data, ULONG len,
dict->dict.strings[id].dictionary = &dict->dict;
dict->dict.strings[id].id = id;
dict->dict.stringCount++;
+
+ dict->sequence[id] = dict->current_sequence;
+
if (ret_id) *ret_id = id;
return S_OK;
}
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index bfc3202a64..d981527bb2 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -43,6 +43,8 @@ struct dictionary
WS_XML_DICTIONARY dict;
ULONG *sorted;
ULONG size;
+ ULONG current_sequence;
+ ULONG *sequence;
};
struct dictionary dict_builtin DECLSPEC_HIDDEN;
const struct dictionary dict_builtin_static DECLSPEC_HIDDEN;
@@ -51,6 +53,7 @@ int find_string( const struct dictionary *, const unsigned char *, ULONG, ULONG
HRESULT insert_string( struct dictionary *, unsigned char *, ULONG, int, ULONG * ) DECLSPEC_HIDDEN;
void clear_dict( struct dictionary * ) DECLSPEC_HIDDEN;
HRESULT writer_set_lookup( WS_XML_WRITER *, BOOL ) DECLSPEC_HIDDEN;
+HRESULT writer_set_dict_callback( WS_XML_WRITER *, WS_DYNAMIC_STRING_CALLBACK, void * ) DECLSPEC_HIDDEN;
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index b3d130a52c..95d4caddb9 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -4866,3 +4866,22 @@ HRESULT writer_set_lookup( WS_XML_WRITER *handle, BOOL enable )
LeaveCriticalSection( &writer->cs );
return S_OK;
}
+
+HRESULT writer_set_dict_callback( WS_XML_WRITER *handle, WS_DYNAMIC_STRING_CALLBACK cb, void *state )
+{
+ struct writer *writer = (struct writer *)handle;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ writer->dict_cb = cb;
+ writer->dict_cb_state = state;
+
+ LeaveCriticalSection( &writer->cs );
+ return S_OK;
+}
--
2.11.0
June 20, 2018
[PATCH 4/5] webservices: Use the static dictionary only while writing the message header.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/channel.c | 30 ++++++++++++++----------------
dlls/webservices/webservices_private.h | 2 +-
dlls/webservices/writer.c | 4 ++--
3 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 6c7c8affa3..79d431f279 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -967,15 +967,6 @@ static HRESULT connect_channel( struct channel *channel )
}
}
-static HRESULT write_message( WS_MESSAGE *handle, WS_XML_WRITER *writer, const WS_ELEMENT_DESCRIPTION *desc,
- WS_WRITE_OPTION option, const void *body, ULONG size )
-{
- HRESULT hr;
- if ((hr = WsWriteEnvelopeStart( handle, writer, NULL, NULL, NULL )) != S_OK) return hr;
- if ((hr = WsWriteBody( handle, desc, option, body, size, NULL )) != S_OK) return hr;
- return WsWriteEnvelopeEnd( handle, NULL );
-}
-
static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len )
{
if (!WinHttpSendRequest( request, NULL, 0, data, len, len, 0 ))
@@ -1298,8 +1289,7 @@ static HRESULT init_writer( struct channel *channel )
bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
bin.dynamicStringCallback = dict_cb;
bin.dynamicStringCallbackState = &channel->dict_send;
- if ((hr = WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL )) != S_OK) return hr;
- return writer_enable_lookup( channel->writer );
+ return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
case WS_ENCODING_XML_BINARY_1:
return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
@@ -1310,6 +1300,17 @@ static HRESULT init_writer( struct channel *channel )
}
}
+static HRESULT write_message( struct channel *channel, WS_MESSAGE *msg, const WS_ELEMENT_DESCRIPTION *desc,
+ WS_WRITE_OPTION option, const void *body, ULONG size )
+{
+ HRESULT hr;
+ if ((hr = writer_set_lookup( channel->writer, TRUE )) != S_OK) return hr;
+ if ((hr = WsWriteEnvelopeStart( msg, channel->writer, NULL, NULL, NULL )) != S_OK) return hr;
+ if ((hr = writer_set_lookup( channel->writer, FALSE )) != S_OK) return hr;
+ if ((hr = WsWriteBody( msg, desc, option, body, size, NULL )) != S_OK) return hr;
+ return WsWriteEnvelopeEnd( msg, NULL );
+}
+
/**************************************************************************
* WsSendMessage [webservices.@]
*/
@@ -1339,8 +1340,7 @@ HRESULT WINAPI WsSendMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_MESS
if ((hr = message_set_action( msg, desc->action )) != S_OK) goto done;
if ((hr = init_writer( channel )) != S_OK) goto done;
- if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
- goto done;
+ if ((hr = write_message( channel, msg, desc->bodyElementDescription, option, body, size )) != S_OK) goto done;
hr = send_message( channel, msg );
done:
@@ -1380,13 +1380,11 @@ HRESULT WINAPI WsSendReplyMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS
if ((hr = message_set_request_id( msg, &req_id )) != S_OK) goto done;
if ((hr = init_writer( channel )) != S_OK) goto done;
- if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
- goto done;
+ if ((hr = write_message( channel, msg, desc->bodyElementDescription, option, body, size )) != S_OK) goto done;
hr = send_message( channel, msg );
done:
LeaveCriticalSection( &channel->cs );
- FIXME( "returning %08x\n", hr );
return hr;
}
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index cce49cce14..bfc3202a64 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -50,7 +50,7 @@ const struct dictionary dict_builtin_static DECLSPEC_HIDDEN;
int find_string( const struct dictionary *, const unsigned char *, ULONG, ULONG * ) DECLSPEC_HIDDEN;
HRESULT insert_string( struct dictionary *, unsigned char *, ULONG, int, ULONG * ) DECLSPEC_HIDDEN;
void clear_dict( struct dictionary * ) DECLSPEC_HIDDEN;
-HRESULT writer_enable_lookup( WS_XML_WRITER * ) DECLSPEC_HIDDEN;
+HRESULT writer_set_lookup( WS_XML_WRITER *, BOOL ) DECLSPEC_HIDDEN;
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index 33c1be70b5..b3d130a52c 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -4849,7 +4849,7 @@ done:
return hr;
}
-HRESULT writer_enable_lookup( WS_XML_WRITER *handle )
+HRESULT writer_set_lookup( WS_XML_WRITER *handle, BOOL enable )
{
struct writer *writer = (struct writer *)handle;
@@ -4861,7 +4861,7 @@ HRESULT writer_enable_lookup( WS_XML_WRITER *handle )
return E_INVALIDARG;
}
- writer->dict_do_lookup = TRUE;
+ writer->dict_do_lookup = enable;
LeaveCriticalSection( &writer->cs );
return S_OK;
--
2.11.0
June 20, 2018
[PATCH 3/5] webservices: Implement WsShutdownSessionChannel.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/channel.c | 98 +++++++++++++++++++++++++++++----------
dlls/webservices/tests/channel.c | 12 +++++
dlls/webservices/webservices.spec | 2 +-
include/webservices.h | 1 +
4 files changed, 87 insertions(+), 26 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 685e13d99d..6c7c8affa3 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -193,6 +193,7 @@ enum session_state
{
SESSION_STATE_UNINITIALIZED,
SESSION_STATE_SETUP_COMPLETE,
+ SESSION_STATE_SHUTDOWN,
};
struct channel
@@ -664,6 +665,78 @@ HRESULT WINAPI WsOpenChannel( WS_CHANNEL *handle, const WS_ENDPOINT_ADDRESS *end
return hr;
}
+enum frame_record_type
+{
+ FRAME_RECORD_TYPE_VERSION,
+ FRAME_RECORD_TYPE_MODE,
+ FRAME_RECORD_TYPE_VIA,
+ FRAME_RECORD_TYPE_KNOWN_ENCODING,
+ FRAME_RECORD_TYPE_EXTENSIBLE_ENCODING,
+ FRAME_RECORD_TYPE_UNSIZED_ENVELOPE,
+ FRAME_RECORD_TYPE_SIZED_ENVELOPE,
+ FRAME_RECORD_TYPE_END,
+ FRAME_RECORD_TYPE_FAULT,
+ FRAME_RECORD_TYPE_UPGRADE_REQUEST,
+ FRAME_RECORD_TYPE_UPGRADE_RESPONSE,
+ FRAME_RECORD_TYPE_PREAMBLE_ACK,
+ FRAME_RECORD_TYPE_PREAMBLE_END,
+};
+
+static HRESULT send_byte( SOCKET socket, BYTE byte )
+{
+ int count = send( socket, (char *)&byte, 1, 0 );
+ if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
+ if (count != 1) return WS_E_OTHER;
+ return S_OK;
+}
+
+static HRESULT shutdown_session( struct channel *channel )
+{
+ HRESULT hr;
+
+ if (channel->state != WS_CHANNEL_STATE_OPEN ||
+ (channel->type != WS_CHANNEL_TYPE_OUTPUT_SESSION &&
+ channel->type != WS_CHANNEL_TYPE_DUPLEX_SESSION) ||
+ channel->session_state >= SESSION_STATE_SHUTDOWN) return WS_E_INVALID_OPERATION;
+
+ switch (channel->binding)
+ {
+ case WS_TCP_CHANNEL_BINDING:
+ if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_END )) != S_OK) return hr;
+ channel->session_state = SESSION_STATE_SHUTDOWN;
+ return S_OK;
+
+ default:
+ FIXME( "unhandled binding %u\n", channel->binding );
+ return E_NOTIMPL;
+ }
+}
+
+HRESULT WINAPI WsShutdownSessionChannel( WS_CHANNEL *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
+{
+ struct channel *channel = (struct channel *)handle;
+ HRESULT hr;
+
+ TRACE( "%p %p %p\n", handle, ctx, error );
+ if (error) FIXME( "ignoring error parameter\n" );
+ if (ctx) FIXME( "ignoring ctx parameter\n" );
+
+ if (!channel) return E_INVALIDARG;
+
+ EnterCriticalSection( &channel->cs );
+
+ if (channel->magic != CHANNEL_MAGIC)
+ {
+ LeaveCriticalSection( &channel->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = shutdown_session( channel );
+
+ LeaveCriticalSection( &channel->cs );
+ return hr;
+}
+
static void close_channel( struct channel *channel )
{
reset_channel( channel );
@@ -913,14 +986,6 @@ static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len )
return S_OK;
}
-static HRESULT send_byte( SOCKET socket, BYTE byte )
-{
- int count = send( socket, (char *)&byte, 1, 0 );
- if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
- if (count != 1) return WS_E_OTHER;
- return S_OK;
-}
-
static HRESULT send_bytes( SOCKET socket, BYTE *bytes, int len )
{
int count = send( socket, (char *)bytes, len, 0 );
@@ -944,23 +1009,6 @@ static HRESULT send_size( SOCKET socket, ULONG size )
return E_INVALIDARG;
}
-enum frame_record_type
-{
- FRAME_RECORD_TYPE_VERSION,
- FRAME_RECORD_TYPE_MODE,
- FRAME_RECORD_TYPE_VIA,
- FRAME_RECORD_TYPE_KNOWN_ENCODING,
- FRAME_RECORD_TYPE_EXTENSIBLE_ENCODING,
- FRAME_RECORD_TYPE_UNSIZED_ENVELOPE,
- FRAME_RECORD_TYPE_SIZED_ENVELOPE,
- FRAME_RECORD_TYPE_END,
- FRAME_RECORD_TYPE_FAULT,
- FRAME_RECORD_TYPE_UPGRADE_REQUEST,
- FRAME_RECORD_TYPE_UPGRADE_RESPONSE,
- FRAME_RECORD_TYPE_PREAMBLE_ACK,
- FRAME_RECORD_TYPE_PREAMBLE_END,
-};
-
static inline ULONG size_length( ULONG size )
{
if (size < 0x80) return 1;
diff --git a/dlls/webservices/tests/channel.c b/dlls/webservices/tests/channel.c
index c995a08829..db17893138 100644
--- a/dlls/webservices/tests/channel.c
+++ b/dlls/webservices/tests/channel.c
@@ -496,6 +496,9 @@ static void test_message_read_write( const struct listener_info *info )
hr = WsOpenChannel( channel, &addr, NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL );
ok( hr == S_OK, "got %08x\n", hr );
@@ -627,6 +630,9 @@ static void test_duplex_session( const struct listener_info *info )
hr = WsCreateChannel( info->type, info->binding, NULL, 0, NULL, &channel, NULL );
ok( hr == S_OK, "got %08x\n", hr );
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
memset( &addr, 0, sizeof(addr) );
addr.url.length = wsprintfW( buf, fmt, info->port );
addr.url.chars = buf;
@@ -655,6 +661,12 @@ static void test_duplex_session( const struct listener_info *info )
err = WaitForSingleObject( info->wait, 3000 );
ok( err == WAIT_OBJECT_0, "wait failed %u\n", err );
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
hr = WsCloseChannel( channel, NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index 55f3e2eaac..8ba34b4209 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -158,7 +158,7 @@
@ stdcall WsSetOutputToBuffer(ptr ptr ptr long ptr)
@ stdcall WsSetReaderPosition(ptr ptr ptr)
@ stdcall WsSetWriterPosition(ptr ptr ptr)
-@ stub WsShutdownSessionChannel
+@ stdcall WsShutdownSessionChannel(ptr ptr ptr)
@ stdcall WsSkipNode(ptr ptr)
@ stub WsStartReaderCanonicalization
@ stub WsStartWriterCanonicalization
diff --git a/include/webservices.h b/include/webservices.h
index 1f823ddc27..928819fc3d 100644
--- a/include/webservices.h
+++ b/include/webservices.h
@@ -1732,6 +1732,7 @@ HRESULT WINAPI WsSetOutputToBuffer(WS_XML_WRITER*, WS_XML_BUFFER*, const WS_XML_
ULONG, WS_ERROR*);
HRESULT WINAPI WsSetReaderPosition(WS_XML_READER*, const WS_XML_NODE_POSITION*, WS_ERROR*);
HRESULT WINAPI WsSetWriterPosition(WS_XML_WRITER*, const WS_XML_NODE_POSITION*, WS_ERROR*);
+HRESULT WINAPI WsShutdownSessionChannel(WS_CHANNEL*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
HRESULT WINAPI WsSkipNode(WS_XML_READER*, WS_ERROR*);
HRESULT WINAPI WsWriteArray(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, WS_VALUE_TYPE,
const void*, ULONG, ULONG, ULONG, WS_ERROR*);
--
2.11.0
June 20, 2018
[PATCH 2/5] webservices: Avoid accessing the old user buffer in WsSetOutput/ToBuffer.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/writer.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index 9cba4e60a2..33c1be70b5 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -39,7 +39,7 @@ static const struct prop_desc writer_props[] =
{
{ sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_MAX_DEPTH */
{ sizeof(BOOL), FALSE }, /* WS_XML_WRITER_PROPERTY_ALLOW_FRAGMENT */
- { sizeof(ULONG), FALSE }, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
+ { sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_MAX_ATTRIBUTES */
{ sizeof(BOOL), FALSE }, /* WS_XML_WRITER_PROPERTY_WRITE_DECLARATION */
{ sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_INDENT */
{ sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_BUFFER_TRIM_SIZE */
@@ -85,6 +85,7 @@ struct writer
WS_CHARSET output_charset;
WS_XML_WRITER_OUTPUT_TYPE output_type;
struct xmlbuf *output_buf;
+ BOOL output_buf_user;
WS_HEAP *output_heap;
const WS_XML_DICTIONARY *dict;
BOOL dict_do_lookup;
@@ -332,7 +333,7 @@ HRESULT WINAPI WsGetWriterProperty( WS_XML_WRITER *handle, WS_XML_WRITER_PROPERT
static void set_output_buffer( struct writer *writer, struct xmlbuf *xmlbuf )
{
/* free current buffer if it's ours */
- if (writer->output_buf && writer->output_buf->heap == writer->output_heap)
+ if (writer->output_buf && !writer->output_buf_user)
{
free_xmlbuf( writer->output_buf );
}
@@ -419,6 +420,7 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
goto done;
}
set_output_buffer( writer, xmlbuf );
+ writer->output_buf_user = FALSE;
break;
}
default:
@@ -472,6 +474,7 @@ HRESULT WINAPI WsSetOutputToBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer
writer->output_enc = xmlbuf->encoding;
writer->output_charset = xmlbuf->charset;
set_output_buffer( writer, xmlbuf );
+ writer->output_buf_user = TRUE;
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
else write_insert_bof( writer, node );
--
2.11.0
June 20, 2018
[PATCH 1/5] webservices: Avoid a warning from HeapDestroy.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/heap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/webservices/heap.c b/dlls/webservices/heap.c
index 5e1a273329..e44cf72e74 100644
--- a/dlls/webservices/heap.c
+++ b/dlls/webservices/heap.c
@@ -216,7 +216,7 @@ HRESULT WINAPI WsCreateHeap( SIZE_T max_size, SIZE_T trim_size, const WS_HEAP_PR
static void reset_heap( struct heap *heap )
{
- HeapDestroy( heap->handle );
+ if (heap->handle) HeapDestroy( heap->handle );
heap->handle = NULL;
heap->max_size = heap->allocated = 0;
}
--
2.11.0
June 20, 2018
Re: [PATCH 6/6] wined3d: Call wined3d_cs_emit_update_sub_resource() directly in buffer_init().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 5/6] wined3d: Use WINED3D_LOCATION_DISCARDED before initializing buffers with data.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 4/6] wined3d: Reduce nesting in texture2d_load_sysmem().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 2/6] wined3d: Initialize depth/stencil texture data.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 3/6] d3d9/tests: Add test for depth stencil initialization.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 1/6] d3d11: Introduce get_resource_properties() helper function.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 2/3] crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.
by Nikolay Sivov
On 06/20/2018 11:10 AM, Alistair Leslie-Hughes wrote:
> Hi Nikolay,
>
> Is there a reason why you didn't include tests in this series?
>
Patch doesn't mention how test blobs were generated, I'd like to find a
reproducible way to recreated them.
>
> Alistair.
>
>
> On 20/06/18 17:37, Nikolay Sivov wrote:
>> From: Michael Müller<michael(a)fds-team.de>
>>
>> Signed-off-by: Nikolay Sivov<nsivov(a)codeweavers.com>
>> ---
>> dlls/crypt32/decode.c | 45 +++++++++++++++++++++++++++++++++++++++++++
>> include/wincrypt.h | 15 +++++++++++++++
>> 2 files changed, 60 insertions(+)
>>
>> diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
>> index a61316016f..4f11d0d60f 100644
>> --- a/dlls/crypt32/decode.c
>> +++ b/dlls/crypt32/decode.c
>> @@ -5973,6 +5973,46 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
>> return ret;
>> }
>>
>> +static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
>> + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
>> + CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
>> +{
>> + DWORD bytesNeeded = 0;
>> + BOOL ret;
>> +
>> + __TRY
>> + {
>> + ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
>> + NULL, &bytesNeeded, NULL);
>> + if (ret)
>> + {
>> + if (!pvStructInfo)
>> + *pcbStructInfo = bytesNeeded;
>> + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
>> + {
>> + LPSTR *info;
>> +
>> + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
>> + pvStructInfo = *(BYTE **)pvStructInfo;
>> +
>> + info = pvStructInfo;
>> + *info = (void *)((BYTE *)info + sizeof(*info));
>> + ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
>> + pvStructInfo, &bytesNeeded, NULL);
>> + if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
>> + CRYPT_FreeSpace(pDecodePara, info);
>> + }
>> + }
>> + }
>> + __EXCEPT_PAGE_FAULT
>> + {
>> + SetLastError(STATUS_ACCESS_VIOLATION);
>> + ret = FALSE;
>> + }
>> + __ENDTRY
>> + return ret;
>> +}
>> +
>> static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
>> LPCSTR lpszStructType)
>> {
>> @@ -6112,6 +6152,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
>> case LOWORD(CMS_SIGNER_INFO):
>> decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
>> break;
>> + case LOWORD(X509_OBJECT_IDENTIFIER):
>> + decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
>> + break;
>> }
>> }
>> else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
>> @@ -6166,6 +6209,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
>> decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
>> else if (!strcmp(lpszStructType, szOID_CTL))
>> decodeFunc = CRYPT_AsnDecodeCTL;
>> + else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
>> + decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
>> return decodeFunc;
>> }
>>
>> diff --git a/include/wincrypt.h b/include/wincrypt.h
>> index 6e71fb902e..a7c24e7831 100644
>> --- a/include/wincrypt.h
>> +++ b/include/wincrypt.h
>> @@ -288,6 +288,11 @@ typedef struct _CERT_KEY_ATTRIBUTES_INFO {
>> PCERT_PRIVATE_KEY_VALIDITY pPrivateKeyUsagePeriod;
>> } CERT_KEY_ATTRIBUTES_INFO, *PCERT_KEY_ATTRIBUTES_INFO;
>>
>> +typedef struct _CERT_ECC_SIGNATURE {
>> + CRYPT_UINT_BLOB r;
>> + CRYPT_UINT_BLOB s;
>> +} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;
>> +
>> /* byte 0 */
>> #define CERT_DIGITAL_SIGNATURE_KEY_USAGE 0x80
>> #define CERT_NON_REPUDIATION_KEY_USAGE 0x40
>> @@ -2878,6 +2883,12 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define szOID_X957 "1.2.840.10040"
>> #define szOID_X957_DSA "1.2.840.10040.4.1"
>> #define szOID_X957_SHA1DSA "1.2.840.10040.4.3"
>> +#define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1"
>> +#define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7"
>> +#define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3"
>> +#define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2"
>> +#define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3"
>> +#define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4"
>> #define szOID_DS "2.5"
>> #define szOID_DSALG "2.5.8"
>> #define szOID_DSALG_CRPT "2.5.8.1"
>> @@ -2919,6 +2930,8 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define szOID_OIWDIR_SIGN "1.3.14.7.2.3"
>> #define szOID_OIWDIR_md2 "1.3.14.7.2.2.1"
>> #define szOID_OIWDIR_md2RSA "1.3.14.7.2.3.1"
>> +#define szOID_ECC_CURVE_P384 "1.3.132.0.34"
>> +#define szOID_ECC_CURVE_P521 "1.3.132.0.35"
>> #define szOID_INFOSEC "2.16.840.1.101.2.1"
>> #define szOID_INFOSEC_sdnsSignature "2.16.840.1.101.2.1.1.1"
>> #define szOID_INFOSEC_mosaicSignature "2.16.840.1.101.2.1.1.2"
>> @@ -3223,6 +3236,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define X509_PKIX_POLICY_QUALIFIER_USERNOTICE ((LPCSTR)46)
>> #define X509_DH_PUBLICKEY X509_MULTI_BYTE_UINT
>> #define X509_DH_PARAMETERS ((LPCSTR)47)
>> +#define X509_ECC_SIGNATURE ((LPCSTR)47)
>> #define PKCS_ATTRIBUTES ((LPCSTR)48)
>> #define PKCS_SORTED_CTL ((LPCSTR)49)
>> #define X942_DH_PARAMETERS ((LPCSTR)50)
>> @@ -3240,6 +3254,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define CMC_ADD_EXTENSIONS ((LPCSTR)62)
>> #define CMC_ADD_ATTRIBUTES ((LPCSTR)63)
>> #define X509_CERTIFICATE_TEMPLATE ((LPCSTR)64)
>> +#define X509_OBJECT_IDENTIFIER ((LPCSTR)73)
>> #define PKCS7_SIGNER_INFO ((LPCSTR)500)
>> #define CMS_SIGNER_INFO ((LPCSTR)501)
>>
>>
>>
>
June 20, 2018
Re: [PATCH 2/3] crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.
by Alistair Leslie-Hughes
Hi Nikolay,
Is there a reason why you didn't include tests in this series?
Alistair.
On 20/06/18 17:37, Nikolay Sivov wrote:
From: Michael Müller <michael(a)fds-team.de><mailto:michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com><mailto:nsivov(a)codeweavers.com>
---
dlls/crypt32/decode.c | 45 +++++++++++++++++++++++++++++++++++++++++++
include/wincrypt.h | 15 +++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index a61316016f..4f11d0d60f 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -5973,6 +5973,46 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ DWORD bytesNeeded = 0;
+ BOOL ret;
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ NULL, &bytesNeeded, NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ LPSTR *info;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+
+ info = pvStructInfo;
+ *info = (void *)((BYTE *)info + sizeof(*info));
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ pvStructInfo, &bytesNeeded, NULL);
+ if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
+ CRYPT_FreeSpace(pDecodePara, info);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
@@ -6112,6 +6152,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(CMS_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
break;
+ case LOWORD(X509_OBJECT_IDENTIFIER):
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
@@ -6166,6 +6209,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
else if (!strcmp(lpszStructType, szOID_CTL))
decodeFunc = CRYPT_AsnDecodeCTL;
+ else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
return decodeFunc;
}
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 6e71fb902e..a7c24e7831 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -288,6 +288,11 @@ typedef struct _CERT_KEY_ATTRIBUTES_INFO {
PCERT_PRIVATE_KEY_VALIDITY pPrivateKeyUsagePeriod;
} CERT_KEY_ATTRIBUTES_INFO, *PCERT_KEY_ATTRIBUTES_INFO;
+typedef struct _CERT_ECC_SIGNATURE {
+ CRYPT_UINT_BLOB r;
+ CRYPT_UINT_BLOB s;
+} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;
+
/* byte 0 */
#define CERT_DIGITAL_SIGNATURE_KEY_USAGE 0x80
#define CERT_NON_REPUDIATION_KEY_USAGE 0x40
@@ -2878,6 +2883,12 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_X957 "1.2.840.10040"
#define szOID_X957_DSA "1.2.840.10040.4.1"
#define szOID_X957_SHA1DSA "1.2.840.10040.4.3"
+#define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1"
+#define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7"
+#define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3"
+#define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2"
+#define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3"
+#define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4"
#define szOID_DS "2.5"
#define szOID_DSALG "2.5.8"
#define szOID_DSALG_CRPT "2.5.8.1"
@@ -2919,6 +2930,8 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_OIWDIR_SIGN "1.3.14.7.2.3"
#define szOID_OIWDIR_md2 "1.3.14.7.2.2.1"
#define szOID_OIWDIR_md2RSA "1.3.14.7.2.3.1"
+#define szOID_ECC_CURVE_P384 "1.3.132.0.34"
+#define szOID_ECC_CURVE_P521 "1.3.132.0.35"
#define szOID_INFOSEC "2.16.840.1.101.2.1"
#define szOID_INFOSEC_sdnsSignature "2.16.840.1.101.2.1.1.1"
#define szOID_INFOSEC_mosaicSignature "2.16.840.1.101.2.1.1.2"
@@ -3223,6 +3236,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define X509_PKIX_POLICY_QUALIFIER_USERNOTICE ((LPCSTR)46)
#define X509_DH_PUBLICKEY X509_MULTI_BYTE_UINT
#define X509_DH_PARAMETERS ((LPCSTR)47)
+#define X509_ECC_SIGNATURE ((LPCSTR)47)
#define PKCS_ATTRIBUTES ((LPCSTR)48)
#define PKCS_SORTED_CTL ((LPCSTR)49)
#define X942_DH_PARAMETERS ((LPCSTR)50)
@@ -3240,6 +3254,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define CMC_ADD_EXTENSIONS ((LPCSTR)62)
#define CMC_ADD_ATTRIBUTES ((LPCSTR)63)
#define X509_CERTIFICATE_TEMPLATE ((LPCSTR)64)
+#define X509_OBJECT_IDENTIFIER ((LPCSTR)73)
#define PKCS7_SIGNER_INFO ((LPCSTR)500)
#define CMS_SIGNER_INFO ((LPCSTR)501)
June 20, 2018
Re: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
by Nikolay Sivov
On 06/16/2018 07:19 PM, Denis Malikov wrote:
> From: Denis Malikov <mdn40000(a)mail.ru>
> Date: Sat, 16 Jun 2018 16:35:45 +0700
> Subject: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
>
> Fix for versions x600 and x620 and pointer calculation for mixing image and mask bits.
>
> Tested on ReactOS 0.4.10 with *.reg files extracted from:
> - XP/2003 key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify;
> - Vista/7 key HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify
>
> Signed-off-by: Denis Malikov <mdn40000(a)mail.ru>
> ---
> dlls/comctl32/imagelist.c | 59 +++++++++++++++++++++++++++--------------------
> 1 file changed, 34 insertions(+), 25 deletions(-)
>
> diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
> index a08d60752e..052d59f9e4 100644
> --- a/dlls/comctl32/imagelist.c
> +++ b/dlls/comctl32/imagelist.c
> @@ -59,7 +59,7 @@ struct _IMAGELIST
> INT cGrow; /* 0C: cGrow */
> INT cx; /* 10: cx */
> INT cy; /* 14: cy */
> - DWORD x4;
> + DWORD x4; /* hack for IL from stream. Keep version here */
> UINT flags; /* 1C: flags */
> COLORREF clrFg; /* 20: foreground color */
> COLORREF clrBk; /* 24: background color */
> @@ -83,6 +83,7 @@ struct _IMAGELIST
> };
The idea is to keep this structure binary compatible, that's why it
starts with a part with specific layout.
If you want to store source stream version, append a new field for that.
I actually like the idea of using
source stream format version to save the list back, it seems like a good
compromise.
>
> #define IMAGELIST_MAGIC 0x53414D58
> +#define IMAGELIST_VERSION 0x101
>
> /* Header used by ImageList_Read() and ImageList_Write() */
> #include "pshpack2.h"
> @@ -806,6 +807,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
> himl->clrFg = CLR_DEFAULT;
> himl->clrBk = CLR_NONE;
> himl->color_table_set = FALSE;
> + himl->x4 = 0;
>
> /* initialize overlay mask indices */
> for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
> @@ -2257,38 +2259,43 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
> BITMAPINFO *image_info = (BITMAPINFO *)image_buf;
> BITMAPINFO *mask_info = (BITMAPINFO *)mask_buf;
> void *image_bits, *mask_bits = NULL;
> - ILHEAD ilHead;
> - HIMAGELIST himl;
> + ILHEAD ilHead;
> + HIMAGELIST himl;
> unsigned int i;
>
> TRACE("%p\n", pstm);
>
> if (FAILED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
> - return NULL;
> + return NULL;
> if (ilHead.usMagic != (('L' << 8) | 'I'))
> - return NULL;
> - if (ilHead.usVersion != 0x101) /* probably version? */
> - return NULL;
> + return NULL;
No need to reformat existing lines.
> + if (ilHead.usVersion != IMAGELIST_VERSION &&
> + ilHead.usVersion != 0x600 && /* XP/2003 version */
> + ilHead.usVersion != 0x620) /* Vista/7 version */
> + return NULL;
The question is if there's any format differences between 0x600 and
0x620, it was probably bumped for a reason.
>
> TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
> ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
>
> himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
> if (!himl)
> - return NULL;
> + return NULL;
> +
> + // keep version from stream
> + himl->x4 = ilHead.usVersion;
No cpp-style comments, please.
>
> @@ -3078,10 +3087,10 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
> TRACE("%p %p\n", himl, pstm);
>
> if (!is_valid(himl))
> - return FALSE;
> + return FALSE;
>
> ilHead.usMagic = (('L' << 8) | 'I');
> - ilHead.usVersion = 0x101;
> + ilHead.usVersion = himl->x4 > 0 ? himl->x4 : IMAGELIST_VERSION;
> ilHead.cCurImage = himl->cCurImage;
> ilHead.cMaxImage = himl->cMaxImage;
> ilHead.cGrow = himl->cGrow;
> @@ -3090,23 +3099,23 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
> ilHead.bkcolor = himl->clrBk;
> ilHead.flags = himl->flags;
> for(i = 0; i < 4; i++) {
> - ilHead.ovls[i] = himl->nOvlIdx[i];
> + ilHead.ovls[i] = himl->nOvlIdx[i];
> }
>
> TRACE("cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
> ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
>
> if(FAILED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
> - return FALSE;
> + return FALSE;
>
> /* write the bitmap */
> if(!_write_bitmap(himl->hbmImage, pstm))
> - return FALSE;
> + return FALSE;
>
> /* write the mask if we have one */
> if(himl->flags & ILC_MASK) {
> - if(!_write_bitmap(himl->hbmMask, pstm))
> - return FALSE;
> + if(!_write_bitmap(himl->hbmMask, pstm))
> + return FALSE;
> }
Doesn't this write in old format, with mismatching version field?
June 20, 2018
[PATCH 3/3] crypt32: Implement decoding of X509_ECC_SIGNATURE.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/decode.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 4f11d0d60f..080feeca0a 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -6013,6 +6013,35 @@ static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret;
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_INTEGER, offsetof(CERT_ECC_SIGNATURE, r),
+ CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_UINT_BLOB), FALSE,
+ TRUE, offsetof(CERT_ECC_SIGNATURE, r.pbData), 0 },
+ { ASN_INTEGER, offsetof(CERT_ECC_SIGNATURE, s),
+ CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_UINT_BLOB), FALSE,
+ TRUE, offsetof(CERT_ECC_SIGNATURE, s.pbData), 0 },
+ };
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
+ pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
+ pcbStructInfo, NULL, NULL);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
@@ -6155,6 +6184,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(X509_OBJECT_IDENTIFIER):
decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
break;
+ case LOWORD(X509_ECC_SIGNATURE):
+ decodeFunc = CRYPT_AsnDecodeEccSignature;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
--
2.17.1
June 20, 2018
[PATCH 2/3] crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/decode.c | 45 +++++++++++++++++++++++++++++++++++++++++++
include/wincrypt.h | 15 +++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index a61316016f..4f11d0d60f 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -5973,6 +5973,46 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ DWORD bytesNeeded = 0;
+ BOOL ret;
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ NULL, &bytesNeeded, NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ LPSTR *info;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+
+ info = pvStructInfo;
+ *info = (void *)((BYTE *)info + sizeof(*info));
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ pvStructInfo, &bytesNeeded, NULL);
+ if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
+ CRYPT_FreeSpace(pDecodePara, info);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
@@ -6112,6 +6152,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(CMS_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
break;
+ case LOWORD(X509_OBJECT_IDENTIFIER):
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
@@ -6166,6 +6209,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
else if (!strcmp(lpszStructType, szOID_CTL))
decodeFunc = CRYPT_AsnDecodeCTL;
+ else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
return decodeFunc;
}
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 6e71fb902e..a7c24e7831 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -288,6 +288,11 @@ typedef struct _CERT_KEY_ATTRIBUTES_INFO {
PCERT_PRIVATE_KEY_VALIDITY pPrivateKeyUsagePeriod;
} CERT_KEY_ATTRIBUTES_INFO, *PCERT_KEY_ATTRIBUTES_INFO;
+typedef struct _CERT_ECC_SIGNATURE {
+ CRYPT_UINT_BLOB r;
+ CRYPT_UINT_BLOB s;
+} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;
+
/* byte 0 */
#define CERT_DIGITAL_SIGNATURE_KEY_USAGE 0x80
#define CERT_NON_REPUDIATION_KEY_USAGE 0x40
@@ -2878,6 +2883,12 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_X957 "1.2.840.10040"
#define szOID_X957_DSA "1.2.840.10040.4.1"
#define szOID_X957_SHA1DSA "1.2.840.10040.4.3"
+#define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1"
+#define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7"
+#define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3"
+#define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2"
+#define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3"
+#define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4"
#define szOID_DS "2.5"
#define szOID_DSALG "2.5.8"
#define szOID_DSALG_CRPT "2.5.8.1"
@@ -2919,6 +2930,8 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_OIWDIR_SIGN "1.3.14.7.2.3"
#define szOID_OIWDIR_md2 "1.3.14.7.2.2.1"
#define szOID_OIWDIR_md2RSA "1.3.14.7.2.3.1"
+#define szOID_ECC_CURVE_P384 "1.3.132.0.34"
+#define szOID_ECC_CURVE_P521 "1.3.132.0.35"
#define szOID_INFOSEC "2.16.840.1.101.2.1"
#define szOID_INFOSEC_sdnsSignature "2.16.840.1.101.2.1.1.1"
#define szOID_INFOSEC_mosaicSignature "2.16.840.1.101.2.1.1.2"
@@ -3223,6 +3236,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define X509_PKIX_POLICY_QUALIFIER_USERNOTICE ((LPCSTR)46)
#define X509_DH_PUBLICKEY X509_MULTI_BYTE_UINT
#define X509_DH_PARAMETERS ((LPCSTR)47)
+#define X509_ECC_SIGNATURE ((LPCSTR)47)
#define PKCS_ATTRIBUTES ((LPCSTR)48)
#define PKCS_SORTED_CTL ((LPCSTR)49)
#define X942_DH_PARAMETERS ((LPCSTR)50)
@@ -3240,6 +3254,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define CMC_ADD_EXTENSIONS ((LPCSTR)62)
#define CMC_ADD_ATTRIBUTES ((LPCSTR)63)
#define X509_CERTIFICATE_TEMPLATE ((LPCSTR)64)
+#define X509_OBJECT_IDENTIFIER ((LPCSTR)73)
#define PKCS7_SIGNER_INFO ((LPCSTR)500)
#define CMS_SIGNER_INFO ((LPCSTR)501)
--
2.17.1
June 20, 2018
[PATCH 1/3] crypt32: Use ARRAY_SIZE macro.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/cert.c | 3 +-
dlls/crypt32/chain.c | 20 ++---
dlls/crypt32/crypt32_private.h | 2 +
dlls/crypt32/decode.c | 89 +++++++++----------
dlls/crypt32/encode.c | 52 +++++------
dlls/crypt32/filestore.c | 3 +-
dlls/crypt32/msg.c | 2 +-
dlls/crypt32/object.c | 155 ++++++++++++---------------------
dlls/crypt32/oid.c | 9 +-
dlls/crypt32/regstore.c | 9 +-
dlls/crypt32/rootstore.c | 6 +-
dlls/crypt32/sip.c | 5 +-
dlls/crypt32/store.c | 7 +-
dlls/crypt32/str.c | 6 +-
14 files changed, 150 insertions(+), 218 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index a4b43ff155..83aac5d8f4 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -987,8 +987,7 @@ static BOOL container_matches_cert(PCCERT_CONTEXT pCert, LPCSTR container,
WCHAR containerW[MAX_PATH];
BOOL matches;
- MultiByteToWideChar(CP_ACP, 0, container, -1,
- containerW, sizeof(containerW) / sizeof(containerW[0]));
+ MultiByteToWideChar(CP_ACP, 0, container, -1, containerW, ARRAY_SIZE(containerW));
/* We make a copy of the CRYPT_KEY_PROV_INFO because the caller expects
* keyProvInfo->pwszContainerName to be NULL or a heap-allocated container
* name.
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index aab2e91583..dd3fc33db6 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -146,9 +146,9 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, co
worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, myW);
worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, trustW);
- CRYPT_AddStoresToCollection(engine->hWorld, sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
- CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
- CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
+ CRYPT_AddStoresToCollection(engine->hWorld, ARRAY_SIZE(worldStores), worldStores);
+ CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
+ CRYPT_CloseStores(ARRAY_SIZE(worldStores), worldStores);
engine->dwFlags = config->dwFlags;
engine->dwUrlRetrievalTimeout = config->dwUrlRetrievalTimeout;
@@ -1688,11 +1688,9 @@ static LPCSTR filetime_to_str(const FILETIME *time)
if (!time) return "(null)";
- GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt,
- sizeof(dateFmt) / sizeof(dateFmt[0]));
+ GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt, ARRAY_SIZE(dateFmt));
FileTimeToSystemTime(time, &sysTime);
- GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date,
- sizeof(date) / sizeof(date[0]));
+ GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date, ARRAY_SIZE(date));
return wine_dbg_sprintf("%s", date);
}
@@ -3117,8 +3115,7 @@ static BOOL WINAPI verify_authenticode_policy(LPCSTR szPolicyOID,
};
/* Check whether the root is an MS test root */
- for (i = 0; !isMSTestRoot && i < sizeof(keyBlobs) / sizeof(keyBlobs[0]);
- i++)
+ for (i = 0; !isMSTestRoot && i < ARRAY_SIZE(keyBlobs); i++)
{
msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
@@ -3408,7 +3405,7 @@ static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name)
end = dot ? dot : ptr + strlenW(ptr);
len = end - ptr;
- if (len >= sizeof(component) / sizeof(component[0]))
+ if (len >= ARRAY_SIZE(component))
{
WARN_(chain)("domain component %s too long\n",
debugstr_wn(ptr, len));
@@ -3690,8 +3687,7 @@ static BOOL WINAPI verify_ms_root_policy(LPCSTR szPolicyOID,
PCCERT_CONTEXT root =
rootChain->rgpElement[rootChain->cElement - 1]->pCertContext;
- for (i = 0; !isMSRoot && i < sizeof(keyBlobs) / sizeof(keyBlobs[0]);
- i++)
+ for (i = 0; !isMSRoot && i < ARRAY_SIZE(keyBlobs); i++)
{
msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 8b1b003a12..dbf6dca411 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -21,6 +21,8 @@
#include "wine/list.h"
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
/* a few asn.1 tags we need */
#define ASN_BOOL (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x01)
#define ASN_BITSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 8b84388b12..a61316016f 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -890,7 +890,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -935,7 +935,7 @@ static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, NULL);
return ret;
@@ -1020,7 +1020,7 @@ static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
NULL, NULL);
if (ret && pvStructInfo)
@@ -1135,7 +1135,7 @@ static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
entry ? entry->SerialNumber.pbData : NULL);
if (ret && entry && !entry->SerialNumber.cbData)
@@ -1236,9 +1236,8 @@ static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
- pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
- NULL, NULL);
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
@@ -1433,7 +1432,7 @@ static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
if (ext)
TRACE("ext->pszObjId is %p\n", ext->pszObjId);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
pcbDecoded, ext ? ext->pszObjId : NULL);
if (ext)
@@ -1871,7 +1870,7 @@ static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
if (attr)
TRACE("attr->pszObjId is %p\n", attr->pszObjId);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
attr ? attr->pszObjId : NULL);
if (attr)
@@ -1968,7 +1967,7 @@ static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
if (attr)
TRACE("attr->pszObjId is %p\n", attr->pszObjId);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
attr ? attr->pszObjId : NULL);
if (attr)
@@ -2197,7 +2196,7 @@ static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
return ret;
@@ -2300,7 +2299,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -2330,7 +2329,7 @@ static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, capability ? capability->pszObjId : NULL);
TRACE("returning %d\n", ret);
@@ -2460,7 +2459,7 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
NULL);
if (ret)
@@ -2496,10 +2495,8 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
*(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
- ret = CRYPT_AsnDecodeSequence(items,
- sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
- NULL, noticeRef, &bytesNeeded, pcbDecoded,
- noticeRef->pszOrganization);
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags,
+ NULL, noticeRef, &bytesNeeded, pcbDecoded, noticeRef->pszOrganization);
}
}
TRACE("returning %d\n", ret);
@@ -2653,7 +2650,7 @@ static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, notice ? notice->pNoticeReference : NULL);
TRACE("returning %d\n", ret);
@@ -2748,7 +2745,7 @@ static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, attr ? attr->pszObjId : NULL);
TRACE("returning %d\n", ret);
@@ -2866,7 +2863,7 @@ static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, algo ? algo->pszObjId : NULL);
if (ret && pvStructInfo)
@@ -2893,7 +2890,7 @@ static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
};
PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
return ret;
@@ -3150,7 +3147,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3187,7 +3184,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
AuthorityCertSerialNumber.pbData), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3214,7 +3211,7 @@ static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
};
CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
- return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ return CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, descr ? descr->pszAccessMethod : NULL);
}
@@ -3323,7 +3320,7 @@ static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->pszObjId : NULL);
return ret;
@@ -3392,7 +3389,7 @@ BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
NULL, NULL);
return ret;
@@ -3531,7 +3528,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3560,7 +3557,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3592,7 +3589,7 @@ static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
return ret;
@@ -3637,7 +3634,7 @@ static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
return ret;
@@ -3694,7 +3691,7 @@ static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
return ret;
@@ -3851,7 +3848,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
TRUE, FALSE, 0, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3890,7 +3887,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
DWORD size = 0;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
&size, NULL, NULL);
if (ret)
@@ -3998,7 +3995,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType,
struct DECODED_RSA_PRIV_KEY *decodedKey = NULL;
DWORD size = 0;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
&size, NULL, NULL);
if (ret)
@@ -5242,7 +5239,7 @@ static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
CRL_DIST_POINT *point = pvStructInfo;
BOOL ret;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
return ret;
@@ -5344,7 +5341,7 @@ static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -5427,7 +5424,7 @@ static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
if (pcbDecoded)
@@ -5508,7 +5505,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -5538,7 +5535,7 @@ static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
@@ -5585,7 +5582,7 @@ static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->Issuer.pbData : NULL);
return ret;
@@ -5751,7 +5748,7 @@ static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
return ret;
@@ -5851,7 +5848,7 @@ BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, signedInfo, pcbSignedInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
NULL, NULL);
TRACE("returning %d\n", ret);
@@ -5884,7 +5881,7 @@ static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData :
NULL);
@@ -5941,7 +5938,7 @@ static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->contentType : NULL);
TRACE("returning %d\n", ret);
@@ -5969,7 +5966,7 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, envelopedData, pcbEnvelopedData);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData,
pcbEnvelopedData, NULL, NULL);
TRACE("returning %d\n", ret);
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index 6f9f595f4f..62d2bc91f7 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -372,7 +372,7 @@ static BOOL WINAPI CRYPT_AsnEncodeValidity(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -400,7 +400,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAlgorithmIdWithNullParams(
else
items[1].pvStructInfo = &nullBlob;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -417,7 +417,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAlgorithmId(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -439,7 +439,7 @@ static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType,
TRACE("Encoding public key with OID %s\n",
debugstr_a(info->Algorithm.pszObjId));
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT_PAGE_FAULT
@@ -469,7 +469,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].encodeFunc = CRYPT_AsnEncodeBits;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT_PAGE_FAULT
@@ -495,7 +495,7 @@ BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType,
TRACE("Encoding public key with OID %s\n",
debugstr_a(info->Algorithm.pszObjId));
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -1530,7 +1530,7 @@ static BOOL CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY *entry,
BOOL ret;
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
+ ARRAY_SIZE(items), 0, NULL, pbEncoded, pcbEncoded);
return ret;
}
@@ -1679,7 +1679,7 @@ static BOOL CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
}
@@ -1822,7 +1822,7 @@ static BOOL WINAPI CRYPT_AsnEncodeNoticeReference(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -1887,7 +1887,7 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSAttribute(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
}
@@ -1960,8 +1960,7 @@ BOOL CRYPT_AsnEncodePKCSDigestedData(const CRYPT_DIGESTED_DATA *digestedData,
{ &digestedData->hash, CRYPT_AsnEncodeOctets, 0 },
};
- return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pvData, pcbData);
+ return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, ARRAY_SIZE(items), 0, NULL, pvData, pcbData);
}
static BOOL WINAPI CRYPT_AsnEncodePKCSContentInfo(DWORD dwCertEncodingType,
@@ -2708,8 +2707,7 @@ static BOOL CRYPT_AsnEncodeAccessDescription(
SetLastError(E_INVALIDARG);
return FALSE;
}
- return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
+ return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, ARRAY_SIZE(items), 0, NULL, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeAuthorityInfoAccess(DWORD dwCertEncodingType,
@@ -2877,8 +2875,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
items[0].pvStructInfo =
info->rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo = &info->rgPolicyQualifier[i].Qualifier;
- ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items),
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size);
if (ret)
bytesNeeded += size;
@@ -2909,8 +2906,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
items[1].pvStructInfo =
&info->rgPolicyQualifier[i].Qualifier;
size = bytesNeeded;
- ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items),
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, out, &size);
if (ret)
{
@@ -2942,8 +2938,7 @@ static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType,
SetLastError(E_INVALIDARG);
return FALSE;
}
- ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded);
+ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items), dwFlags, NULL, pbEncoded, pcbEncoded);
return ret;
}
@@ -3026,8 +3021,7 @@ static BOOL CRYPT_AsnEncodeCertPolicyMapping(DWORD dwCertEncodingType,
SetLastError(E_INVALIDARG);
return FALSE;
}
- return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded);
+ return CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items), dwFlags, NULL, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeCertPolicyMappings(DWORD dwCertEncodingType,
@@ -3169,8 +3163,7 @@ static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
}
__EXCEPT_PAGE_FAULT
@@ -4151,8 +4144,7 @@ static BOOL WINAPI CRYPT_AsnEncodeIssuerSerialNumber(
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
@@ -4402,8 +4394,7 @@ static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType,
};
return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeEncryptedContentInfo(DWORD dwCertEncodingType,
@@ -4421,8 +4412,7 @@ static BOOL WINAPI CRYPT_AsnEncodeEncryptedContentInfo(DWORD dwCertEncodingType,
};
return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
@@ -4439,7 +4429,7 @@ BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
};
return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pvData, pcbData);
+ ARRAY_SIZE(items), 0, NULL, pvData, pcbData);
}
static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
diff --git a/dlls/crypt32/filestore.c b/dlls/crypt32/filestore.c
index 0f7d8d5150..9c211e14b1 100644
--- a/dlls/crypt32/filestore.c
+++ b/dlls/crypt32/filestore.c
@@ -231,8 +231,7 @@ static WINECRYPT_CERTSTORE *CRYPT_CreateFileStore(DWORD dwFlags,
info->type = type;
info->dirty = FALSE;
provInfo.cbSize = sizeof(provInfo);
- provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
- sizeof(fileProvFuncs[0]);
+ provInfo.cStoreProvFunc = ARRAY_SIZE(fileProvFuncs);
provInfo.rgpvStoreProvFunc = fileProvFuncs;
provInfo.hStoreProv = info;
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index fd43a7baeb..005fbf2c1f 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -175,7 +175,7 @@ static BOOL CRYPT_EncodeDataContentInfoHeader(const CDataEncodeMsg *msg,
};
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), CRYPT_ENCODE_ALLOC_FLAG, NULL,
+ ARRAY_SIZE(items), CRYPT_ENCODE_ALLOC_FLAG, NULL,
(LPBYTE)&header->pbData, &header->cbData);
if (ret)
{
diff --git a/dlls/crypt32/object.c b/dlls/crypt32/object.c
index 0320cfda1b..3dc28af0e9 100644
--- a/dlls/crypt32/object.c
+++ b/dlls/crypt32/object.c
@@ -929,8 +929,7 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
DWORD bytesNeeded = sizeof(WCHAR);
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
if (!bits->cbData || bits->cbData > 2)
{
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
@@ -959,26 +958,18 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- for (i = 0;
- i < sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]);
- i++)
- LoadStringW(hInstance, keyUsageByte0Map[i].id,
- keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
- for (i = 0;
- i < sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]);
- i++)
- LoadStringW(hInstance, keyUsageByte1Map[i].id,
- keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
+ for (i = 0; i < ARRAY_SIZE(keyUsageByte0Map); i++)
+ LoadStringW(hInstance, keyUsageByte0Map[i].id, keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
+ for (i = 0; i < ARRAY_SIZE(keyUsageByte1Map); i++)
+ LoadStringW(hInstance, keyUsageByte1Map[i].id, keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
stringsLoaded = TRUE;
}
- CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
- sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
- NULL, &bitStringLen, &first);
+ CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map, ARRAY_SIZE(keyUsageByte0Map),
+ NULL, &bitStringLen, &first);
bytesNeeded += bitStringLen;
if (bits->cbData == 2)
{
- CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
- sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+ CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map, ARRAY_SIZE(keyUsageByte1Map),
NULL, &bitStringLen, &first);
bytesNeeded += bitStringLen;
}
@@ -1000,15 +991,13 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
bitStringLen = bytesNeeded;
first = TRUE;
- CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
- sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
+ CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map, ARRAY_SIZE(keyUsageByte0Map),
str, &bitStringLen, &first);
str += bitStringLen / sizeof(WCHAR) - 1;
if (bits->cbData == 2)
{
bitStringLen = bytesNeeded;
- CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
- sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+ CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map, ARRAY_SIZE(keyUsageByte1Map),
str, &bitStringLen, &first);
str += bitStringLen / sizeof(WCHAR) - 1;
}
@@ -1070,15 +1059,10 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_SUBJECT_TYPE, subjectTypeHeader,
- sizeof(subjectTypeHeader) / sizeof(subjectTypeHeader[0]));
- LoadStringW(hInstance, IDS_SUBJECT_TYPE_CA, subjectTypeCA,
- sizeof(subjectTypeCA) / sizeof(subjectTypeCA[0]));
- LoadStringW(hInstance, IDS_SUBJECT_TYPE_END_CERT,
- subjectTypeEndCert,
- sizeof(subjectTypeEndCert) / sizeof(subjectTypeEndCert[0]));
- LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader,
- sizeof(pathLengthHeader) / sizeof(pathLengthHeader[0]));
+ LoadStringW(hInstance, IDS_SUBJECT_TYPE, subjectTypeHeader, ARRAY_SIZE(subjectTypeHeader));
+ LoadStringW(hInstance, IDS_SUBJECT_TYPE_CA, subjectTypeCA, ARRAY_SIZE(subjectTypeCA));
+ LoadStringW(hInstance, IDS_SUBJECT_TYPE_END_CERT, subjectTypeEndCert, ARRAY_SIZE(subjectTypeEndCert));
+ LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader, ARRAY_SIZE(pathLengthHeader));
stringsLoaded = TRUE;
}
bytesNeeded += strlenW(subjectTypeHeader) * sizeof(WCHAR);
@@ -1092,8 +1076,7 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType,
if (info->fPathLenConstraint)
sprintfW(pathLength, pathFmt, info->dwPathLenConstraint);
else
- LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength,
- sizeof(pathLength) / sizeof(pathLength[0]));
+ LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength, ARRAY_SIZE(pathLength));
bytesNeeded += strlenW(pathLength) * sizeof(WCHAR);
if (!pbFormat)
*pcbFormat = bytesNeeded;
@@ -1130,7 +1113,7 @@ static BOOL CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB *blob, int id,
DWORD bytesNeeded;
BOOL ret;
- LoadStringW(hInstance, id, buf, sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, id, buf, ARRAY_SIZE(buf));
CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL,
blob->pbData, blob->cbData, NULL, &bytesNeeded);
bytesNeeded += strlenW(buf) * sizeof(WCHAR);
@@ -1189,14 +1172,12 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
switch (entry->dwAltNameChoice)
{
case CERT_ALT_NAME_RFC822_NAME:
- LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf, ARRAY_SIZE(buf));
bytesNeeded += strlenW(entry->u.pwszRfc822Name) * sizeof(WCHAR);
ret = TRUE;
break;
case CERT_ALT_NAME_DNS_NAME:
- LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf, ARRAY_SIZE(buf));
bytesNeeded += strlenW(entry->u.pwszDNSName) * sizeof(WCHAR);
ret = TRUE;
break;
@@ -1208,8 +1189,7 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
strType |= CERT_NAME_STR_CRLF_FLAG;
directoryNameLen = cert_name_to_str_with_indent(X509_ASN_ENCODING,
indentLevel + 1, &entry->u.DirectoryName, strType, NULL, 0);
- LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf, ARRAY_SIZE(buf));
bytesNeeded += (directoryNameLen - 1) * sizeof(WCHAR);
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
bytesNeeded += strlenW(colonCrlf) * sizeof(WCHAR);
@@ -1219,8 +1199,7 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
break;
}
case CERT_ALT_NAME_URL:
- LoadStringW(hInstance, IDS_ALT_NAME_URL, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_URL, buf, ARRAY_SIZE(buf));
bytesNeeded += strlenW(entry->u.pwszURL) * sizeof(WCHAR);
ret = TRUE;
break;
@@ -1232,14 +1211,12 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
static const WCHAR ipAddrFmt[] = { '%','d','.','%','d','.','%','d',
'.','%','d',0 };
- LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf, ARRAY_SIZE(buf));
if (entry->u.IPAddress.cbData == 8)
{
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
{
- LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask,
- sizeof(mask) / sizeof(mask[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask, ARRAY_SIZE(mask));
bytesNeeded += strlenW(mask) * sizeof(WCHAR);
sprintfW(ipAddrBuf, ipAddrFmt,
entry->u.IPAddress.pbData[0],
@@ -1448,7 +1425,7 @@ static BOOL CRYPT_FormatCertIssuer(DWORD dwFormatStrType,
LPCWSTR sep;
BOOL ret;
- LoadStringW(hInstance, IDS_CERT_ISSUER, buf, sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_CERT_ISSUER, buf, ARRAY_SIZE(buf));
ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, NULL,
&bytesNeeded);
bytesNeeded += strlenW(buf) * sizeof(WCHAR);
@@ -1652,8 +1629,7 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType,
{
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
if (!pbFormat)
*pcbFormat = bytesNeeded;
@@ -1680,18 +1656,12 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_AIA, aia,
- sizeof(aia) / sizeof(aia[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD, accessMethod,
- sizeof(accessMethod) / sizeof(accessMethod[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD_OCSP, ocsp,
- sizeof(ocsp) / sizeof(ocsp[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD_CA_ISSUERS, caIssuers,
- sizeof(caIssuers) / sizeof(caIssuers[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD_UNKNOWN, unknown,
- sizeof(unknown) / sizeof(unknown[0]));
- LoadStringW(hInstance, IDS_ACCESS_LOCATION, accessLocation,
- sizeof(accessLocation) / sizeof(accessLocation[0]));
+ LoadStringW(hInstance, IDS_AIA, aia, ARRAY_SIZE(aia));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD, accessMethod, ARRAY_SIZE(accessMethod));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD_OCSP, ocsp, ARRAY_SIZE(ocsp));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD_CA_ISSUERS, caIssuers, ARRAY_SIZE(caIssuers));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD_UNKNOWN, unknown, ARRAY_SIZE(unknown));
+ LoadStringW(hInstance, IDS_ACCESS_LOCATION, accessLocation, ARRAY_SIZE(accessLocation));
stringsLoaded = TRUE;
}
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
@@ -1879,7 +1849,7 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
if (!stringsLoaded)
{
- for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reason_map); i++)
LoadStringW(hInstance, reason_map[i].id, reason_map[i].reason,
MAX_STRING_RESOURCE_LEN);
stringsLoaded = TRUE;
@@ -1887,7 +1857,7 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
/* No need to check reasonFlags->cbData, we already know it's positive.
* Ignore any other bytes, as they're for undefined bits.
*/
- for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reason_map); i++)
{
if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
{
@@ -1909,14 +1879,13 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
else
{
*pcbStr = bytesNeeded;
- for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reason_map); i++)
{
if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
{
strcpyW(str, reason_map[i].reason);
str += strlenW(reason_map[i].reason);
- if (i < sizeof(reason_map) / sizeof(reason_map[0]) - 1 &&
- numReasons)
+ if (i < ARRAY_SIZE(reason_map) - 1 && numReasons)
{
strcpyW(str, sep);
str += strlenW(sep);
@@ -1963,18 +1932,12 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_CRL_DIST_POINT, crlDistPoint,
- sizeof(crlDistPoint) / sizeof(crlDistPoint[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_NAME, distPointName,
- sizeof(distPointName) / sizeof(distPointName[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_FULL_NAME, fullName,
- sizeof(fullName) / sizeof(fullName[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_RDN_NAME, rdnName,
- sizeof(rdnName) / sizeof(rdnName[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_REASON, reason,
- sizeof(reason) / sizeof(reason[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_ISSUER, issuer,
- sizeof(issuer) / sizeof(issuer[0]));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT, crlDistPoint, ARRAY_SIZE(crlDistPoint));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_NAME, distPointName, ARRAY_SIZE(distPointName));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_FULL_NAME, fullName, ARRAY_SIZE(fullName));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_RDN_NAME, rdnName, ARRAY_SIZE(rdnName));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_REASON, reason, ARRAY_SIZE(reason));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_ISSUER, issuer, ARRAY_SIZE(issuer));
stringsLoaded = TRUE;
}
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
@@ -2050,8 +2013,7 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType,
{
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
if (!pbFormat)
*pcbFormat = bytesNeeded;
@@ -2202,8 +2164,7 @@ static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType,
sepLen = strlenW(commaSpace) * sizeof(WCHAR);
}
- LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown,
- sizeof(unknown) / sizeof(unknown[0]));
+ LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown, ARRAY_SIZE(unknown));
for (i = 0; i < usage->cUsageIdentifier; i++)
{
PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
@@ -2299,8 +2260,7 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
DWORD bytesNeeded = sizeof(WCHAR);
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
if (!bits->cbData || bits->cbData > 1)
{
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
@@ -2329,15 +2289,13 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- for (i = 0; i < sizeof(netscapeCertTypeMap) /
- sizeof(netscapeCertTypeMap[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(netscapeCertTypeMap); i++)
LoadStringW(hInstance, netscapeCertTypeMap[i].id,
netscapeCertTypeMap[i].str, MAX_STRING_RESOURCE_LEN);
stringsLoaded = TRUE;
}
- CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
- sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
- NULL, &bitStringLen, &first);
+ CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap, ARRAY_SIZE(netscapeCertTypeMap),
+ NULL, &bitStringLen, &first);
bytesNeeded += bitStringLen;
bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
@@ -2357,9 +2315,8 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
bitStringLen = bytesNeeded;
first = TRUE;
- CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
- sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
- str, &bitStringLen, &first);
+ CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap, ARRAY_SIZE(netscapeCertTypeMap),
+ str, &bitStringLen, &first);
str += bitStringLen / sizeof(WCHAR) - 1;
*str++ = ' ';
*str++ = '(';
@@ -2407,16 +2364,12 @@ static BOOL WINAPI CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA, financialCriteria,
- sizeof(financialCriteria) / sizeof(financialCriteria[0]));
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_AVAILABLE, available,
- sizeof(available) / sizeof(available[0]));
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE,
- notAvailable, sizeof(notAvailable) / sizeof(notAvailable[0]));
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA,
- meetsCriteria, sizeof(meetsCriteria) / sizeof(meetsCriteria[0]));
- LoadStringW(hInstance, IDS_YES, yes, sizeof(yes) / sizeof(yes[0]));
- LoadStringW(hInstance, IDS_NO, no, sizeof(no) / sizeof(no[0]));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA, financialCriteria, ARRAY_SIZE(financialCriteria));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_AVAILABLE, available, ARRAY_SIZE(available));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE, notAvailable, ARRAY_SIZE(notAvailable));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA, meetsCriteria, ARRAY_SIZE(meetsCriteria));
+ LoadStringW(hInstance, IDS_YES, yes, ARRAY_SIZE(yes));
+ LoadStringW(hInstance, IDS_NO, no, ARRAY_SIZE(no));
stringsLoaded = TRUE;
}
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
diff --git a/dlls/crypt32/oid.c b/dlls/crypt32/oid.c
index 5a447d09ca..61b2cbc88e 100644
--- a/dlls/crypt32/oid.c
+++ b/dlls/crypt32/oid.c
@@ -69,7 +69,7 @@ static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',
static const WCHAR TRUSTEDPUBLISHER[] = {'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0};
static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0};
static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED};
-static WCHAR LocalizedNames[sizeof(LocalizedKeys)/sizeof(LocalizedKeys[0])][256];
+static WCHAR LocalizedNames[ARRAY_SIZE(LocalizedKeys)][256];
static void free_function_sets(void)
{
@@ -1006,7 +1006,7 @@ static void oid_init_localizednames(void)
{
unsigned int i;
- for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
+ for(i = 0; i < ARRAY_SIZE(LocalizedKeys); i++)
{
LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
}
@@ -1019,7 +1019,7 @@ LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
{
unsigned int i;
- for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
+ for(i = 0; i < ARRAY_SIZE(LocalizedKeys); i++)
{
if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
{
@@ -1399,8 +1399,7 @@ static void init_oid_info(void)
DWORD i;
oid_init_localizednames();
- for (i = 0; i < sizeof(oidInfoConstructors) /
- sizeof(oidInfoConstructors[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(oidInfoConstructors); i++)
{
if (!IS_INTRESOURCE(oidInfoConstructors[i].pwszName))
{
diff --git a/dlls/crypt32/regstore.c b/dlls/crypt32/regstore.c
index 7678bab6aa..ce32a30f3b 100644
--- a/dlls/crypt32/regstore.c
+++ b/dlls/crypt32/regstore.c
@@ -71,7 +71,7 @@ static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType,
WCHAR subKeyName[MAX_PATH];
do {
- DWORD size = sizeof(subKeyName) / sizeof(WCHAR);
+ DWORD size = ARRAY_SIZE(subKeyName);
rc = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL, NULL,
NULL);
@@ -163,7 +163,7 @@ static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store)
CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG };
DWORD i;
- for (i = 0; i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(subKeys); i++)
{
HKEY hKey;
LONG rc;
@@ -255,7 +255,7 @@ static BOOL CRYPT_RegWriteToReg(WINE_REGSTOREINFO *store)
BOOL ret = TRUE;
DWORD i;
- for (i = 0; ret && i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
+ for (i = 0; ret && i < ARRAY_SIZE(subKeys); i++)
{
HKEY key;
LONG rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0,
@@ -561,8 +561,7 @@ WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore);
regInfo->dirty = FALSE;
provInfo.cbSize = sizeof(provInfo);
- provInfo.cStoreProvFunc = sizeof(regProvFuncs) /
- sizeof(regProvFuncs[0]);
+ provInfo.cStoreProvFunc = ARRAY_SIZE(regProvFuncs);
provInfo.rgpvStoreProvFunc = regProvFuncs;
provInfo.hStoreProv = regInfo;
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
diff --git a/dlls/crypt32/rootstore.c b/dlls/crypt32/rootstore.c
index 73d954f740..e7ed4e9bea 100644
--- a/dlls/crypt32/rootstore.c
+++ b/dlls/crypt32/rootstore.c
@@ -780,7 +780,7 @@ static void add_ms_root_certs(HCERTSTORE to)
TRACE("\n");
- for (i = 0; i < sizeof(msRootCerts) / sizeof(msRootCerts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(msRootCerts); i++)
if (!CertAddEncodedCertificateToStore(to, X509_ASN_ENCODING,
msRootCerts[i].pb, msRootCerts[i].cb, CERT_STORE_ADD_NEW, NULL))
WARN("adding root cert %d failed: %08x\n", i, GetLastError());
@@ -830,9 +830,7 @@ static void read_trusted_roots_from_known_locations(HCERTSTORE store)
}
#endif
- for (i = 0; !ret &&
- i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
- i++)
+ for (i = 0; !ret && i < ARRAY_SIZE(CRYPT_knownLocations); i++)
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
check_and_store_certs(from, store);
}
diff --git a/dlls/crypt32/sip.c b/dlls/crypt32/sip.c
index b0c4692c1f..f51bceb460 100644
--- a/dlls/crypt32/sip.c
+++ b/dlls/crypt32/sip.c
@@ -28,6 +28,7 @@
#include "winnls.h"
#include "mssip.h"
#include "winuser.h"
+#include "crypt32_private.h"
#include "wine/debug.h"
#include "wine/list.h"
@@ -440,7 +441,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
WCHAR subKeyName[MAX_PATH];
do {
- size = sizeof(subKeyName) / sizeof(subKeyName[0]);
+ size = ARRAY_SIZE(subKeyName);
r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
NULL, NULL);
if (r == ERROR_SUCCESS)
@@ -478,7 +479,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
WCHAR subKeyName[MAX_PATH];
do {
- size = sizeof(subKeyName) / sizeof(subKeyName[0]);
+ size = ARRAY_SIZE(subKeyName);
r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
NULL, NULL);
if (r == ERROR_SUCCESS)
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index bc4ebde5f6..2b8ea1d5d8 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -124,7 +124,7 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
/* Poor-man's resync: empty first store, then add everything from second
* store to it.
*/
- for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(interfaces); i++)
{
const void *context;
@@ -717,8 +717,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
CERT_STORE_PROV_INFO provInfo = { 0 };
provInfo.cbSize = sizeof(provInfo);
- provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
- sizeof(msgProvFuncs[0]);
+ provInfo.cStoreProvFunc = ARRAY_SIZE(msgProvFuncs);
provInfo.rgpvStoreProvFunc = msgProvFuncs;
provInfo.hStoreProv = CryptMsgDuplicate(msg);
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
@@ -1338,7 +1337,7 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
ret = TRUE;
do {
WCHAR name[MAX_PATH];
- DWORD size = sizeof(name) / sizeof(name[0]);
+ DWORD size = ARRAY_SIZE(name);
rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
NULL);
diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index 1daf29f8a0..4843c4f5f1 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -26,6 +26,7 @@
#include "wincrypt.h"
#include "wine/debug.h"
#include "wine/unicode.h"
+#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -775,7 +776,7 @@ struct KeynameKeeper
static void CRYPT_InitializeKeynameKeeper(struct KeynameKeeper *keeper)
{
keeper->keyName = keeper->buf;
- keeper->keyLen = sizeof(keeper->buf) / sizeof(keeper->buf[0]);
+ keeper->keyLen = ARRAY_SIZE(keeper->buf);
}
static void CRYPT_FreeKeynameKeeper(struct KeynameKeeper *keeper)
@@ -1326,8 +1327,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
{
PCERT_RDN_ATTR nameAttr = NULL;
- for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
- sizeof(simpleAttributeOIDs[0]); i++)
+ for (i = 0; !nameAttr && i < ARRAY_SIZE(simpleAttributeOIDs); i++)
nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo);
if (nameAttr)
ret = CertRDNValueToStrW(nameAttr->dwValueType,
--
2.17.1
June 20, 2018
Re: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
by Zhiyi Zhang
Hi Denis,
Thanks for taking the time. I noticed a few issues with your patch.
1. Using C++ style comments.
2. Mixing style only changes, please separate them if you really
need to make style changes. Usually, I prefer not to touch the old
code simply for style changes.
3. Add a conformance test for the problem you intent to fix.
4. Add a version to patch mail subject.
You might want to read
https://wiki.winehq.org/Submitting_Patches
Regards,
Zhiyi
June 20, 2018
[PATCH v3 2/2] gdiplus: Avoid calling GdipFillPath() with an empty path.
by Zhiyi Zhang
There is no point filling an empty path. And an empty
path will cause SelectClipPath() used in brush_fill_path()
to return error.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdiplus/graphics.c | 3 +++
dlls/gdiplus/tests/graphics.c | 47 +++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index a793665683..2d23085e8a 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -4264,6 +4264,9 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p
if(graphics->busy)
return ObjectBusy;
+ if (!path->pathdata.Count)
+ return Ok;
+
if (graphics->image && graphics->image->type == ImageTypeMetafile)
return METAFILE_FillPath((GpMetafile*)graphics->image, brush, path);
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index ae75c0efc1..5eb0a8a4d0 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -1539,6 +1539,52 @@ static void test_GdipFillClosedCurveI(void)
ReleaseDC(hwnd, hdc);
}
+static void test_GdipFillPath(void)
+{
+ GpStatus status;
+ GpGraphics *graphics;
+ GpSolidFill *brush;
+ GpPath *path;
+ HDC hdc = GetDC(hwnd);
+
+ ok(hdc != NULL, "Expected HDC to be initialized\n");
+ status = GdipCreateFromHDC(hdc, &graphics);
+ expect(Ok, status);
+ ok(graphics != NULL, "Expected graphics to be initialized\n");
+ status = GdipCreateSolidFill((ARGB)0xffffffff, &brush);
+ expect(Ok, status);
+ ok(brush != NULL, "Expected brush to be initialized\n");
+ status = GdipCreatePath(FillModeAlternate, &path);
+ expect(Ok, status);
+ ok(path != NULL, "Expected path to be initialized\n");
+
+ /* Empty path */
+ GdipResetPath(path);
+ status = GdipFillPath(graphics, (GpBrush *)brush, path);
+ expect(Ok, status);
+
+ /* Not closed path */
+ GdipResetPath(path);
+ status = GdipAddPathLineI(path, 0, 0, 2, 2);
+ expect(Ok, status);
+ status = GdipAddPathLineI(path, 2, 2, 4, 0);
+ expect(Ok, status);
+ status = GdipFillPath(graphics, (GpBrush *)brush, path);
+ expect(Ok, status);
+
+ /* Closed path */
+ GdipResetPath(path);
+ status = GdipAddPathRectangle(path, 0, 0, 4, 4);
+ expect(Ok, status);
+ status = GdipFillPath(graphics, (GpBrush *)brush, path);
+ expect(Ok, status);
+
+ GdipDeletePath(path);
+ GdipDeleteBrush((GpBrush *)brush);
+ GdipDeleteGraphics(graphics);
+ ReleaseDC(hwnd, hdc);
+}
+
static void test_Get_Release_DC(void)
{
GpStatus status;
@@ -6795,6 +6841,7 @@ START_TEST(graphics)
test_GdipDrawImagePointsRect();
test_GdipFillClosedCurve();
test_GdipFillClosedCurveI();
+ test_GdipFillPath();
test_GdipDrawString();
test_GdipGetNearestColor();
test_GdipGetVisibleClipBounds();
--
2.17.1
June 20, 2018
[PATCH v3 1/2] gdiplus: Report error for brush_fill_path().
by Zhiyi Zhang
Operation should be skipped if SelectClipPath() returns any
error. And we should report unexpected error to the caller.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdiplus/graphics.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 894e879233..a793665683 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -1050,8 +1050,9 @@ static BOOL brush_can_fill_path(GpBrush *brush, BOOL is_fill)
}
}
-static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
+static GpStatus brush_fill_path(GpGraphics *graphics, GpBrush *brush)
{
+ GpStatus status = Ok;
switch (brush->bt)
{
case BrushTypeSolidColor:
@@ -1064,13 +1065,19 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
RECT rc;
/* partially transparent fill */
- SelectClipPath(graphics->hdc, RGN_AND);
+ if (!SelectClipPath(graphics->hdc, RGN_AND))
+ {
+ status = GenericError;
+ DeleteObject(bmp);
+ break;
+ }
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
{
HDC hdc = CreateCompatibleDC(NULL);
if (!hdc)
{
+ status = OutOfMemory;
DeleteObject(bmp);
break;
}
@@ -1091,7 +1098,11 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
HBRUSH gdibrush, old_brush;
gdibrush = create_gdi_brush(brush);
- if (!gdibrush) return;
+ if (!gdibrush)
+ {
+ status = OutOfMemory;
+ break;
+ }
old_brush = SelectObject(graphics->hdc, gdibrush);
FillPath(graphics->hdc);
@@ -1100,6 +1111,8 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
break;
}
}
+
+ return status;
}
static BOOL brush_can_fill_pixels(GpBrush *brush)
@@ -4205,7 +4218,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath
if(retval == Ok)
{
EndPath(graphics->hdc);
- brush_fill_path(graphics, brush);
+ retval = brush_fill_path(graphics, brush);
}
gdi_transform_release(graphics);
@@ -4511,13 +4524,13 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
Rectangle(graphics->hdc, rc.left, rc.top, rc.right, rc.bottom);
EndPath(graphics->hdc);
- brush_fill_path(graphics, brush);
+ status = brush_fill_path(graphics, brush);
}
RestoreDC(graphics->hdc, save_state);
- return Ok;
+ return status;
}
static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
--
2.17.1
June 20, 2018
[PATCH] comctl32/imagelist: fix ImageList_Read/Write.
by Denis Malikov
From: Denis Malikov <mdn40000(a)mail.ru>
Date: Sat, 16 Jun 2018 16:35:45 +0700
Subject: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
Fix pointer calculation for mixing image and mask bits for versions x600 and x620.
Tested with *.reg files extracted from:
XP/2003 key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify;
Vista/7 key HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify
Signed-off-by: Denis Malikov <mdn40000(a)mail.ru>
---
dlls/comctl32/imagelist.c | 59 +++++++++++++++++++++++++++--------------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index a08d60752e..052d59f9e4 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -59,7 +59,7 @@ struct _IMAGELIST
INT cGrow; /* 0C: cGrow */
INT cx; /* 10: cx */
INT cy; /* 14: cy */
- DWORD x4;
+ DWORD x4; /* hack for IL from stream. Keep version here */
UINT flags; /* 1C: flags */
COLORREF clrFg; /* 20: foreground color */
COLORREF clrBk; /* 24: background color */
@@ -83,6 +83,7 @@ struct _IMAGELIST
};
#define IMAGELIST_MAGIC 0x53414D58
+#define IMAGELIST_VERSION 0x101
/* Header used by ImageList_Read() and ImageList_Write() */
#include "pshpack2.h"
@@ -806,6 +807,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
himl->clrFg = CLR_DEFAULT;
himl->clrBk = CLR_NONE;
himl->color_table_set = FALSE;
+ himl->x4 = 0;
/* initialize overlay mask indices */
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
@@ -2257,38 +2259,43 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
BITMAPINFO *image_info = (BITMAPINFO *)image_buf;
BITMAPINFO *mask_info = (BITMAPINFO *)mask_buf;
void *image_bits, *mask_bits = NULL;
- ILHEAD ilHead;
- HIMAGELIST himl;
+ ILHEAD ilHead;
+ HIMAGELIST himl;
unsigned int i;
TRACE("%p\n", pstm);
if (FAILED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
- return NULL;
+ return NULL;
if (ilHead.usMagic != (('L' << 8) | 'I'))
- return NULL;
- if (ilHead.usVersion != 0x101) /* probably version? */
- return NULL;
+ return NULL;
+ if (ilHead.usVersion != IMAGELIST_VERSION &&
+ ilHead.usVersion != 0x600 && /* XP/2003 version */
+ ilHead.usVersion != 0x620) /* Vista/7 version */
+ return NULL;
TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
if (!himl)
- return NULL;
+ return NULL;
+
+ // keep version from stream
+ himl->x4 = ilHead.usVersion;
if (!(image_bits = read_bitmap(pstm, image_info)))
{
- WARN("failed to read bitmap from stream\n");
- return NULL;
+ WARN("failed to read bitmap from stream\n");
+ return NULL;
}
if (ilHead.flags & ILC_MASK)
{
if (!(mask_bits = read_bitmap(pstm, mask_info)))
{
WARN("failed to read mask bitmap from stream\n");
- return NULL;
- }
+ return NULL;
+ }
}
else mask_info = NULL;
@@ -2296,23 +2303,25 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
{
DWORD *ptr = image_bits;
BYTE *mask_ptr = mask_bits;
- int stride = himl->cy * image_info->bmiHeader.biWidth;
+ int stride = himl->cy * (ilHead.usVersion != IMAGELIST_VERSION ? himl->cx : image_info->bmiHeader.biWidth);
+ int image_step = ilHead.usVersion != IMAGELIST_VERSION ? 1 : TILE_COUNT;
+ int mask_step = ilHead.usVersion != IMAGELIST_VERSION ? 4 : 8;
if (image_info->bmiHeader.biHeight > 0) /* bottom-up */
{
ptr += image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride;
- mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / 8;
+ mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / mask_step;
stride = -stride;
image_info->bmiHeader.biHeight = himl->cy;
}
else image_info->bmiHeader.biHeight = -himl->cy;
- for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT)
+ for (i = 0; i < ilHead.cCurImage; i += image_step)
{
- add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ),
+ add_dib_bits( himl, i, min( ilHead.cCurImage - i, image_step ),
himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr );
ptr += stride;
- mask_ptr += stride / 8;
+ mask_ptr += stride / mask_step;
}
}
else
@@ -2333,7 +2342,7 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
ImageList_SetBkColor(himl,ilHead.bkcolor);
for (i=0;i<4;i++)
- ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
+ ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
return himl;
}
@@ -3078,10 +3087,10 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
TRACE("%p %p\n", himl, pstm);
if (!is_valid(himl))
- return FALSE;
+ return FALSE;
ilHead.usMagic = (('L' << 8) | 'I');
- ilHead.usVersion = 0x101;
+ ilHead.usVersion = himl->x4 > 0 ? himl->x4 : IMAGELIST_VERSION;
ilHead.cCurImage = himl->cCurImage;
ilHead.cMaxImage = himl->cMaxImage;
ilHead.cGrow = himl->cGrow;
@@ -3090,23 +3099,23 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
ilHead.bkcolor = himl->clrBk;
ilHead.flags = himl->flags;
for(i = 0; i < 4; i++) {
- ilHead.ovls[i] = himl->nOvlIdx[i];
+ ilHead.ovls[i] = himl->nOvlIdx[i];
}
TRACE("cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
if(FAILED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
- return FALSE;
+ return FALSE;
/* write the bitmap */
if(!_write_bitmap(himl->hbmImage, pstm))
- return FALSE;
+ return FALSE;
/* write the mask if we have one */
if(himl->flags & ILC_MASK) {
- if(!_write_bitmap(himl->hbmMask, pstm))
- return FALSE;
+ if(!_write_bitmap(himl->hbmMask, pstm))
+ return FALSE;
}
return TRUE;
--
2.16.2.windows.1
June 20, 2018
[PATCH] wsdapi: Add a trailing '\n' to a WARN() message.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/wsdapi/network.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wsdapi/network.c b/dlls/wsdapi/network.c
index e124a5d90cf..c8f260c7653 100644
--- a/dlls/wsdapi/network.c
+++ b/dlls/wsdapi/network.c
@@ -540,7 +540,7 @@ static BOOL start_listening_on_all_addresses(IWSDiscoveryPublisherImpl *impl, UL
{
if (impl->num_thread_handles >= MAX_WSD_THREADS)
{
- WARN("Exceeded maximum number of supported listener threads; too many network interfaces.");
+ WARN("Exceeded maximum number of supported listener threads; too many network interfaces.\n");
goto cleanup;
}
--
2.17.1
June 20, 2018
[PATCH] winetest: Don't show dll=skipped messages for skipped tests.
by Francois Gouget
This spams the report when using WineTest to run a few tests.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
programs/winetest/main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c
index bfac17bdf6e..b3c3c1c8502 100644
--- a/programs/winetest/main.c
+++ b/programs/winetest/main.c
@@ -902,7 +902,6 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (test_filtered_out( lpszName, NULL ))
{
nr_of_skips++;
- xprintf (" %s=skipped\n", dllname);
return TRUE;
}
extract_test (&wine_tests[nr_of_files], tempdir, lpszName);
--
2.17.1
June 20, 2018
[PATCH 2/2] testbot/web: Highlight test failures and build errors on the job page.
by Francois Gouget
Show build errors in the log summary mode (like we already do for the
test failures).
Furthermore, when showing the full log, highlight the test failures and
build errors so they are easier to spot. This uses the same color
scheme as in the test.winehq.org website. Also make the boundaries
between the test units more visible by highlighting their start line.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 61 +++++++++++++++++++++++++++++++++----
testbot/web/WineTestBot.css | 5 +++
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index f829407eb..3add52b4c 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -228,6 +228,58 @@ sub GeneratePage($)
$self->SUPER::GeneratePage();
}
+sub GetHtmlLine($$$)
+{
+ my ($self, $FullLog, $Line) = @_;
+
+ $Line = $self->escapeHTML($Line);
+ if ($Line =~ /: Test marked todo: /)
+ {
+ return (undef, $Line) if (!$FullLog);
+ my $Html = $Line;
+ $Html =~ s~^(.*\S)\s*\r?$~<span class='log-todo'>$1</span>~;
+ return ($Html, $Line);
+ }
+ if ($Line =~ /: Tests skipped: / or
+ $Line =~ /^\w+:\w+ skipped /)
+ {
+ return (undef, $Line) if (!$FullLog);
+ my $Html = $Line;
+ $Html =~ s~^(.*\S)\s*\r?$~<span class='log-skip'>$1</span>~;
+ return ($Html, $Line);
+ }
+ if ($Line =~ /: Test (?:failed|succeeded inside todo block): / or
+ $Line =~ /Fatal: test .* does not exist/ or
+ $Line =~ / done \(258\)/ or
+ $Line =~ /: unhandled exception [0-9a-fA-F]{8} at / or
+ $Line =~ /^Unhandled exception: / or
+ # Build errors
+ $Line =~ /: error: / or
+ $Line =~ /^error: patch failed:/ or
+ $Line =~ /^Makefile:[0-9]+: recipe for target .* failed$/ or
+ $Line =~ /^(?:Build|Reconfig|Task): (?!ok)/ or
+ # Typical perl errors
+ $Line =~ /^Use of uninitialized value/)
+ {
+ return ($Line, $Line) if (!$FullLog);
+ my $Html = $Line;
+ $Html =~ s~^(.*\S)\s*\r?$~<span class='log-error'>$1</span>~;
+ return ($Html, $Line);
+ }
+ if ($FullLog &&
+ ($Line =~ /^\+ \S/ or
+ $Line =~ /^\w+:\w+ start / or
+ # Build messages
+ $Line =~ /^(?:Build|Reconfig|Task): ok/))
+ {
+ my $Html = $Line;
+ $Html =~ s~^(.*\S)\s*\r?$~<span class='log-info'>$1</span>~;
+ return ($Html, $Line);
+ }
+
+ return (undef, $Line);
+}
+
my %MILogLabels = (
"log" => "task log",
"log.old" => "old logs",
@@ -371,11 +423,8 @@ sub GenerateBody($)
{
$CurrentDll = $1;
}
- if ($MoreInfo->{Full} ||
- $Line =~ m/: Test (?:failed|succeeded inside todo block): / ||
- $Line =~ m/Fatal: test '[^']+' does not exist/ ||
- $Line =~ m/ done \(258\)/ ||
- $Line =~ m/: unhandled exception [0-9a-fA-F]{8} at /)
+ my ($Highlight, $Plain) = $self->GetHtmlLine($MoreInfo->{Full}, $Line);
+ if ($MoreInfo->{Full} || defined $Highlight)
{
if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
{
@@ -402,7 +451,7 @@ sub GenerateBody($)
}
else
{
- print $self->escapeHTML($Line), "\n";
+ print(($Highlight || $Plain), "\n");
}
}
}
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index ebc622e34..28ac1b1c2 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -353,6 +353,11 @@ pre
.boterror { color: #e55600; }
.canceled { color: black; }
+.log-info { background-color: #d9ffcc; }
+.log-skip { color: blue; }
+.log-todo { color: #d08000; }
+.log-error { color: red; }
+
a.title { color:inherit; text-decoration: none; }
th.Record { text-align: center; }
--
2.17.1
June 20, 2018
[PATCH 1/2] testbot/web: Allow showing multiple job screenshots and logs.
by Francois Gouget
It's now possible to have the job details page show multiple
screenshots and multiple logs.
Once a screenshot / log is shown, the link can be clicked again to hide
it.
The code can also more easily be extended to handle more log files.
The code inserting the links is simpler too.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 2 +-
testbot/web/JobDetails.pl | 156 +++++++++++++++++++++++--------------
2 files changed, 97 insertions(+), 61 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 3d8113fd9..c4ca578e2 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -448,7 +448,7 @@ elsif ($Step->Type eq "suite")
if (defined($WebHostName))
{
my $StepTask = 100 * $StepNo + $TaskNo;
- $Script .= "-u \"http://$WebHostName/JobDetails.pl?Key=$JobId&scrshot_$StepTask=1#k$StepTask\"";
+ $Script .= "-u \"http://$WebHostName/JobDetails.pl?Key=$JobId&s$StepTask=1#k$StepTask\"";
}
my $Info = $VM->Description ? $VM->Description : "";
if ($VM->Details)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 70d8b5983..f829407eb 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -228,12 +228,95 @@ sub GeneratePage($)
$self->SUPER::GeneratePage();
}
+my %MILogLabels = (
+ "log" => "task log",
+ "log.old" => "old logs",
+);
+
+sub InitMoreInfo($)
+{
+ my ($self) = @_;
+
+ my $More = $self->{More} = {};
+ my $Keys = $self->SortKeys(undef, $self->{Collection}->GetKeys());
+ foreach my $Key (@$Keys)
+ {
+ my $StepTask = $self->{Collection}->GetItem($Key);
+ $More->{$Key}->{Screenshot} = $self->GetParam("s$Key");
+
+ my $Value = $self->GetParam("f$Key");
+ my $TaskDir = $StepTask->GetTaskDir();
+ foreach my $Log ("log", "log.old")
+ {
+ if (!-f "$TaskDir/$Log" or -z "$TaskDir/$Log")
+ {
+ my $Err = $Log;
+ next if ($Err !~ s/^log/err/ or !-f "$TaskDir/$Err" or -z "$TaskDir/$Err");
+ }
+ push @{$More->{$Key}->{Logs}}, $Log;
+
+ $More->{$Key}->{Full} = $Log if (uri_escape($Log) eq $Value);
+ }
+ $More->{$Key}->{Full} ||= "";
+ }
+}
+
+sub GenerateMoreInfoLink($$$;$)
+{
+ my ($self, $LinkKey, $Label, $Set, $Value) = @_;
+
+ my $Url = $ENV{"SCRIPT_NAME"} ."?Key=". uri_escape($self->{JobId});
+
+ my $Action = "Show";
+ foreach my $Key (sort keys %{$self->{More}})
+ {
+ my $MoreInfo = $self->{More}->{$Key};
+ if ($Key eq $LinkKey and $Set eq "Screenshot")
+ {
+ if (!$MoreInfo->{Screenshot})
+ {
+ $Url .= "&s$Key=1";
+ }
+ else
+ {
+ $Action = "Hide";
+ }
+ }
+ else
+ {
+ $Url .= "&s$Key=1" if ($MoreInfo->{Screenshot});
+ }
+
+ if ($Key eq $LinkKey and $Set eq "Full")
+ {
+ if ($MoreInfo->{Full} ne $Value)
+ {
+ $Url .= "&f$Key=". uri_escape($Value);
+ }
+ else
+ {
+ $Action = "Hide";
+ }
+ }
+ else
+ {
+ $Url .= "&f$Key=". uri_escape($MoreInfo->{Full}) if ($MoreInfo->{Full});
+ }
+ }
+ $Url .= "#k" . uri_escape($LinkKey);
+
+ print "<div class='TaskMoreInfoLink'><a href='",
+ $self->CGI->escapeHTML($Url), "'>$Action $Label</a></div>\n";
+}
+
sub GenerateBody($)
{
my ($self) = @_;
$self->SUPER::GenerateBody();
+ $self->InitMoreInfo();
+
print "<div class='Content'>\n";
my $Keys = $self->SortKeys(undef, $self->{Collection}->GetKeys());
foreach my $Key (@$Keys)
@@ -249,18 +332,11 @@ sub GenerateBody($)
$self->CGI->escapeHTML($VM->Details || "No details!"),
"</details>\n";
- my $FullLogParamName = "log_$Key";
- my $FullLog = $self->GetParam($FullLogParamName);
- $FullLog = "" if ($FullLog !~ /^[12]$/);
-
- my $ScreenshotParamName = "scrshot_$Key";
- my $Screenshot = $self->GetParam($ScreenshotParamName);
- $Screenshot = "" if ($Screenshot ne "1");
-
+ my $MoreInfo = $self->{More}->{$Key};
print "<div class='TaskMoreInfoLinks'>\n";
if (-r "$TaskDir/screenshot.png")
{
- if ($Screenshot)
+ if ($MoreInfo->{Screenshot})
{
my $URI = "/Screenshot.pl?JobKey=" . uri_escape($self->{JobId}) .
"&StepKey=" . uri_escape($StepTask->StepNo) .
@@ -268,59 +344,19 @@ sub GenerateBody($)
print "<div class='Screenshot'><img src='" .
$self->CGI->escapeHTML($URI) . "' alt='Screenshot' /></div>\n";
}
- else
- {
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId}) .
- "&$ScreenshotParamName=1";
- $URI .= "&$FullLogParamName=$FullLog";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show final screenshot</a></div>";
- print "\n";
- }
+ $self->GenerateMoreInfoLink($Key, "final screenshot", "Screenshot");
}
- my $LogName = "$TaskDir/log";
- my $ErrName = "$TaskDir/err";
- if (-r $LogName and $FullLog != "1")
- {
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId}) .
- "&$FullLogParamName=1";
- $URI .= "&$ScreenshotParamName=$Screenshot";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show full log</a></div>\n";
- }
- if ((-r $LogName or -r $ErrName) and $FullLog == "2")
+ foreach my $Log (@{$MoreInfo->{Logs}})
{
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId});
- $URI .= "&$ScreenshotParamName=$Screenshot";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show latest log</a></div>\n";
- }
- if ((-r "$LogName.old" or -r "$ErrName.old") and $FullLog != "2")
- {
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId}) .
- "&$FullLogParamName=2";
- $URI .= "&$ScreenshotParamName=$Screenshot";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show old logs</a></div>\n";
+ $self->GenerateMoreInfoLink($Key, $MILogLabels{$Log}, "Full", $Log);
}
print "</div>\n";
- if ($FullLog eq "2")
- {
- $LogName .= ".old";
- $ErrName .= ".old";
- }
+ my $LogName = $MoreInfo->{Full} || $MoreInfo->{Logs}->[0] || "log";
+ my $ErrName = $LogName eq "log.old" ? "err.old" : "err";
- if (open LOGFILE, "<$LogName")
+ if (open LOGFILE, "<", "$TaskDir/$LogName")
{
my $HasLogEntries = !1;
my $First = 1;
@@ -335,13 +371,13 @@ sub GenerateBody($)
{
$CurrentDll = $1;
}
- if ($FullLog ||
+ if ($MoreInfo->{Full} ||
$Line =~ m/: Test (?:failed|succeeded inside todo block): / ||
$Line =~ m/Fatal: test '[^']+' does not exist/ ||
$Line =~ m/ done \(258\)/ ||
$Line =~ m/: unhandled exception [0-9a-fA-F]{8} at /)
{
- if ($PrintedDll ne $CurrentDll && ! $FullLog)
+ if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
{
if ($First)
{
@@ -359,7 +395,7 @@ sub GenerateBody($)
print "<pre><code>";
$First = !1;
}
- if (! $FullLog && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
+ if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
{
my $Unit = $1 ne "" ? "$1: " : "";
print "${Unit}Timeout\n";
@@ -372,7 +408,7 @@ sub GenerateBody($)
}
close LOGFILE;
- if (open ERRFILE, "<$ErrName")
+ if (open ERRFILE, "<", "$TaskDir/$ErrName")
{
$CurrentDll = "*err*";
while (defined($Line = <ERRFILE>))
@@ -409,7 +445,7 @@ sub GenerateBody($)
" failures found" : "Empty log";
}
}
- elsif (open ERRFILE, "<$ErrName")
+ elsif (open ERRFILE, "<", "$TaskDir/$ErrName")
{
my $HasErrEntries = !1;
my $Line;
--
2.17.1
June 20, 2018
[PATCH 4/4] testbot/build: Let the TestBot deal with logging.
by Francois Gouget
The Engine-side scripts (WineRun*.pl) already redirect stdout and
stderr to the appropriate log. So it does not make sense to delete that
log and then add new redirects for every command started from the
client scripts.
Remove FatalError() since it's not used in Reconfig.pl.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 42 ++++++++------------------
testbot/bin/build/Reconfig.pl | 55 +++++++++++------------------------
2 files changed, 29 insertions(+), 68 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index e97995559..c23bb8780 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -49,27 +49,19 @@ use WineTestBot::PatchUtils;
use WineTestBot::Utils;
-my $LogFileName = "$LogDir/Build.log";
-
sub InfoMsg(@)
{
- my $OldUMask = umask(002);
- if (open(my $Log, ">>", $LogFileName))
- {
- print $Log @_;
- close($Log);
- }
- umask($OldUMask);
+ print @_;
}
sub LogMsg(@)
{
- InfoMsg "Build: ", @_;
+ print "Build: ", @_;
}
sub FatalError(@)
{
- LogMsg @_;
+ print STDERR @_;
exit 1;
}
@@ -90,10 +82,9 @@ sub ApplyPatch($)
my ($PatchFile) = @_;
InfoMsg "Applying patch\n";
- system("( cd $DataDir/wine && set -x && " .
- " git apply --verbose ". ShQuote($PatchFile) ." && ".
- " git add -A " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && set -x && ".
+ "git apply --verbose ". ShQuote($PatchFile) ." && ".
+ "git add -A");
if ($? != 0)
{
LogMsg "Patch failed to apply\n";
@@ -104,9 +95,7 @@ sub ApplyPatch($)
if ($Impacts->{Makefiles})
{
InfoMsg "\nRunning make_makefiles\n";
- system("( cd $DataDir/wine && set -x && " .
- " ./tools/make_makefiles " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && set -x && ./tools/make_makefiles");
if ($? != 0)
{
LogMsg "make_makefiles failed\n";
@@ -117,9 +106,7 @@ sub ApplyPatch($)
if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
{
InfoMsg "\nRunning autoconf\n";
- system("( cd $DataDir/wine && set -x && " .
- " autoconf " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && set -x && autoconf");
if ($? != 0)
{
LogMsg "Autoconf failed\n";
@@ -135,9 +122,8 @@ sub BuildNative()
mkdir "$DataDir/build-native" if (! -d "$DataDir/build-native");
InfoMsg "\nRebuilding native tools\n";
- system("( cd $DataDir/build-native && set -x && " .
- " time make -j$ncpus __tooldeps__ " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-native && set -x && ".
+ "time make -j$ncpus __tooldeps__");
if ($? != 0)
{
LogMsg "Rebuild of native tools failed\n";
@@ -161,9 +147,8 @@ sub BuildTestExecutables($$)
}
InfoMsg "\nBuilding the $Bits-bit test executable(s)\n";
- system("( cd $DataDir/build-mingw$Bits && set -x && " .
- " time make -j$ncpus ". join(" ", sort @BuildDirs) .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-mingw$Bits && set -x && ".
+ "time make -j$ncpus ". join(" ", sort @BuildDirs));
if ($? != 0)
{
LogMsg "Rebuild of $Bits-bit crossbuild failed\n";
@@ -186,9 +171,6 @@ sub BuildTestExecutables($$)
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
-# Start with a clean logfile
-unlink($LogFileName);
-
my ($PatchFile, $BitIndicators);
if (@ARGV == 2)
{
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index c950d4974..2da2f54a4 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -43,28 +43,15 @@ sub BEGIN
use WineTestBot::Config;
use WineTestBot::PatchUtils;
-my $LogFileName = "$LogDir/Reconfig.log";
sub InfoMsg(@)
{
- my $OldUMask = umask(002);
- if (open(my $Log, ">>", $LogFileName))
- {
- print $Log @_;
- close($Log);
- }
- umask($OldUMask);
+ print @_;
}
sub LogMsg(@)
{
- InfoMsg "Reconfig: ", @_;
-}
-
-sub FatalError(@)
-{
- LogMsg @_;
- exit 1;
+ print "Reconfig: ", @_;
}
my $ncpus;
@@ -86,9 +73,8 @@ sub BuildTestAgentd()
if (! -x "$BinDir/build/testagentd")
{
InfoMsg "\nBuilding the native testagentd\n";
- system("( cd $::RootDir/src/testagentd && set -x && " .
- " time make -j$ncpus build " .
- ") >>$LogFileName 2>&1");
+ system("cd $::RootDir/src/testagentd && set -x && ".
+ "time make -j$ncpus build");
if ($? != 0)
{
LogMsg "Build testagentd failed\n";
@@ -97,9 +83,8 @@ sub BuildTestAgentd()
}
InfoMsg "\nRebuilding the Windows TestAgentd\n";
- system("( cd $::RootDir/src/testagentd && set -x && " .
- " time make -j$ncpus iso " .
- ") >>$LogFileName 2>&1");
+ system("cd $::RootDir/src/testagentd && set -x && ".
+ "time make -j$ncpus iso");
if ($? != 0)
{
LogMsg "Build winetestbot.iso failed\n";
@@ -112,9 +97,8 @@ sub BuildTestAgentd()
sub BuildTestLauncher()
{
InfoMsg "\nRebuilding TestLauncher\n";
- system("( cd $::RootDir/src/TestLauncher && set -x && " .
- " time make -j$ncpus" .
- ") >>$LogFileName 2>&1");
+ system("cd $::RootDir/src/TestLauncher && set -x && ".
+ "time make -j$ncpus");
if ($? != 0)
{
LogMsg "Build TestLauncher failed\n";
@@ -127,7 +111,7 @@ sub BuildTestLauncher()
sub GitPull()
{
InfoMsg "\nUpdating the Wine source\n";
- system("cd $DataDir/wine && git pull >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && git pull");
if ($? != 0)
{
LogMsg "Git pull failed\n";
@@ -150,11 +134,10 @@ sub BuildNative()
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
- system("( cd $DataDir/build-native && set -x && " .
- " rm -rf * && " .
- " time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && " .
- " time make -j$ncpus __tooldeps__ " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-native && set -x && ".
+ "rm -rf * && ".
+ "time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
+ "time make -j$ncpus __tooldeps__");
if ($? != 0)
{
@@ -174,11 +157,10 @@ sub BuildCross($)
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
- system("( cd $DataDir/build-mingw$Bits && set -x && " .
- " rm -rf * && " .
- " time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && " .
- " time make -j$ncpus buildtests" .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-mingw$Bits && set -x && ".
+ "rm -rf * && ".
+ "time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
+ "time make -j$ncpus buildtests");
if ($? != 0)
{
LogMsg "Build cross ($Bits bits) failed\n";
@@ -191,9 +173,6 @@ sub BuildCross($)
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
-# Start with a clean logfile
-unlink($LogFileName);
-
if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
{
LogMsg "Unable to create '$DataDir/staging': $!\n";
--
2.17.1
June 20, 2018
[PATCH 3/4] testbot/Build: Don't use tainting and improve handling of the patch filename.
by Francois Gouget
Tainting is moot because the whole purpose of the script is to run
arbitrary user-provided code (in patch form).
Still validate the patch filename but use the standard IsValidFileName()
function (instead of the much stricter regular expression used so far)
so patches accepted by Submit.pl don't get rejected at this late stage.
However carefully quote the filename when building our shell command so
it does not fail if the filename contains a space (for instance).
Also note that in practice (so far) the patch filename is always called
patch.diff as this is hardcoded in WineRunBuild.pl. So this is all a
bit academic.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 25 ++++++++++++++-----------
testbot/lib/WineTestBot/Utils.pm | 26 +++++++++++++++++++++++++-
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 8318af12a..e97995559 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -1,10 +1,13 @@
-#!/usr/bin/perl -Tw
+#!/usr/bin/perl
# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
#
# Performs the 'build' task in the build machine. Specifically this applies a
# conformance test patch, rebuilds the impacted test and retrieves the
# resulting 32 and 64 bit binaries.
#
+# This script does not use tainting (-T) because its whole purpose is to run
+# arbitrary user-provided code anyway (in patch form).
+#
# Copyright 2009 Ge van Geldorp
# Copyright 2012-2014, 2017-2018 Francois Gouget
#
@@ -22,6 +25,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+use warnings;
use strict;
sub BEGIN
@@ -42,6 +46,8 @@ sub BEGIN
use WineTestBot::Config;
use WineTestBot::PatchUtils;
+use WineTestBot::Utils;
+
my $LogFileName = "$LogDir/Build.log";
@@ -85,7 +91,7 @@ sub ApplyPatch($)
InfoMsg "Applying patch\n";
system("( cd $DataDir/wine && set -x && " .
- " git apply --verbose $PatchFile && " .
+ " git apply --verbose ". ShQuote($PatchFile) ." && ".
" git add -A " .
") >>$LogFileName 2>&1");
if ($? != 0)
@@ -199,18 +205,15 @@ if (! $PatchFile || !$BitIndicators)
FatalError "Usage: Build.pl <patchfile> <bits>\n";
}
-# Untaint parameters
-if ($PatchFile =~ m/^([\w_.\-]+)$/)
+# Verify parameters
+if (!IsValidFileName($PatchFile))
{
- $PatchFile = "$DataDir/staging/$1";
- if (! -r $PatchFile)
- {
- FatalError "Patch file $PatchFile not readable\n";
- }
+ FatalError "The patch filename '$PatchFile' contains invalid characters\n";
}
-else
+$PatchFile = "$DataDir/staging/$PatchFile";
+if (!-r $PatchFile)
{
- FatalError "Invalid patch file $PatchFile\n";
+ FatalError "Patch file '$PatchFile' is not readable\n";
}
my ($Run32, $Run64);
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 962e6ff67..111a56589 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -28,7 +28,8 @@ WineTestBot::Utils - Utility functions
use Exporter 'import';
our @EXPORT = qw(MakeSecureURL SecureConnection GenerateRandomString
OpenNewFile CreateNewFile CreateNewLink CreateNewDir
- DurationToString BuildEMailRecipient IsValidFileName);
+ DurationToString BuildEMailRecipient IsValidFileName
+ ShQuote);
use Fcntl;
@@ -196,4 +197,27 @@ sub IsValidFileName($)
return $FileName !~ m~[<>:"/\\|?*]~;
}
+=pod
+=over 12
+
+=item C<ShQuote()>
+
+Quotes strings so they can be used in shell commands.
+
+Note that this implies escaping '$'s and '`'s which may not be appropriate
+in another context.
+
+=back
+=cut
+
+sub ShQuote($)
+{
+ my ($Str)=@_;
+ $Str =~ s%\\%\\\\%g;
+ $Str =~ s%\$%\\\$%g;
+ $Str =~ s%\"%\\\"%g;
+ $Str =~ s%\`%\\\`%g;
+ return "\"$Str\"";
+}
+
1;
--
2.17.1
June 20, 2018
[PATCH 2/4] testbot/web: Reject filenames that are not valid Windows filenames.
by Francois Gouget
IsValidFileName() verifies that the filename is valid on both Windows
and Unix. This is necessary to ensure we will be able to upload the file
to the build and/or test VMs.
IsValidFileName() is defined in the Utils.pm module so it can be reused
where necessary.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Utils.pm | 25 ++++++++++++++++++++++++-
testbot/web/Submit.pl | 4 ++--
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 8b0bfeb0c..962e6ff67 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -28,7 +28,7 @@ WineTestBot::Utils - Utility functions
use Exporter 'import';
our @EXPORT = qw(MakeSecureURL SecureConnection GenerateRandomString
OpenNewFile CreateNewFile CreateNewLink CreateNewDir
- DurationToString BuildEMailRecipient);
+ DurationToString BuildEMailRecipient IsValidFileName);
use Fcntl;
@@ -173,4 +173,27 @@ sub CreateNewDir($$)
}
}
+
+#
+# Shell helpers
+#
+
+=pod
+=over 12
+
+=item C<IsValidFileName()>
+
+Returns true if the filename is valid on Unix and Windows systems.
+
+This also ensures this is not a trick filename such as '../important/file'.
+
+=back
+=cut
+
+sub IsValidFileName($)
+{
+ my ($FileName) = @_;
+ return $FileName !~ m~[<>:"/\\|?*]~;
+}
+
1;
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index c16b99f1e..afebc722b 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -514,10 +514,10 @@ sub ValidateAndGetFileName($$)
$self->{ErrMessage} = "You must provide a file to test";
return undef;
}
- if ($FileName =~ m=[/\\]=)
+ if (!IsValidFileName($FileName))
{
$self->{ErrField} = $FieldName;
- $self->{ErrMessage} = "The filename is invalid";
+ $self->{ErrMessage} = "The filename contains invalid characters";
return undef;
}
my $PropertyDescriptor = CreateSteps()->GetPropertyDescriptorByName("FileName");
--
2.17.1
June 20, 2018
[PATCH 1/4] testbot: Add section headers and reorder the Utils.pm functions.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Utils.pm | 100 +++++++++++++++++--------------
1 file changed, 54 insertions(+), 46 deletions(-)
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 81a2eda39..8b0bfeb0c 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -35,6 +35,10 @@ use Fcntl;
use WineTestBot::Config;
+#
+# Web helpers
+#
+
sub MakeSecureURL($)
{
my ($URL) = @_;
@@ -53,6 +57,56 @@ sub SecureConnection()
return defined($ENV{"HTTPS"}) && $ENV{"HTTPS"} eq "on";
}
+sub DurationToString($;$)
+{
+ my ($Secs, $Raw) = @_;
+
+ return "n/a" if (!defined $Secs);
+
+ my @Parts;
+ if (!$Raw)
+ {
+ my $Mins = int($Secs / 60);
+ $Secs -= 60 * $Mins;
+ my $Hours = int($Mins / 60);
+ $Mins -= 60 * $Hours;
+ my $Days = int($Hours / 24);
+ $Hours -= 24 * $Days;
+ push @Parts, "${Days}d" if ($Days);
+ push @Parts, "${Hours}h" if ($Hours);
+ push @Parts, "${Mins}m" if ($Mins);
+ }
+ if (!@Parts or int($Secs) != 0)
+ {
+ push @Parts, (@Parts or int($Secs) == $Secs) ?
+ int($Secs) ."s" :
+ sprintf('%.1fs', $Secs);
+ }
+ return join(" ", @Parts);
+}
+
+sub BuildEMailRecipient($$)
+{
+ my ($EMailAddress, $Name) = @_;
+
+ if (! defined($EMailAddress))
+ {
+ return undef;
+ }
+ my $Recipient = "<" . $EMailAddress . ">";
+ if ($Name)
+ {
+ $Recipient .= " ($Name)";
+ }
+
+ return $Recipient;
+}
+
+
+#
+# Temporary file helpers
+#
+
sub GenerateRandomString($)
{
my ($Len) = @_;
@@ -119,50 +173,4 @@ sub CreateNewDir($$)
}
}
-sub DurationToString($;$)
-{
- my ($Secs, $Raw) = @_;
-
- return "n/a" if (!defined $Secs);
-
- my @Parts;
- if (!$Raw)
- {
- my $Mins = int($Secs / 60);
- $Secs -= 60 * $Mins;
- my $Hours = int($Mins / 60);
- $Mins -= 60 * $Hours;
- my $Days = int($Hours / 24);
- $Hours -= 24 * $Days;
- push @Parts, "${Days}d" if ($Days);
- push @Parts, "${Hours}h" if ($Hours);
- push @Parts, "${Mins}m" if ($Mins);
- }
- if (!@Parts or int($Secs) != 0)
- {
- push @Parts, (@Parts or int($Secs) == $Secs) ?
- int($Secs) ."s" :
- sprintf('%.1fs', $Secs);
- }
- return join(" ", @Parts);
-}
-
-sub BuildEMailRecipient($$)
-{
- my ($EMailAddress, $Name) = @_;
-
- if (! defined($EMailAddress))
- {
- return undef;
- }
- my $Recipient = "<" . $EMailAddress . ">";
- if ($Name)
- {
- $Recipient .= " ($Name)";
- }
-
- return $Recipient;
-}
-
-
1;
--
2.17.1
June 20, 2018
[PATCH] testbot/WineRunTask: Trace the effective timeout, with leeway.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 4fd51d985..51b105b19 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -493,7 +493,7 @@ if (!$Pid)
my $NewStatus = 'completed';
my ($TaskFailures, $TaskTimedOut, $TAError, $PossibleCrash);
-Debug(Elapsed($Start), " Waiting for the script (", $Task->Timeout, "s timeout)\n");
+Debug(Elapsed($Start), " Waiting for the script (", $Timeout, "s timeout)\n");
if (!defined $TA->Wait($Pid, $Timeout, $Keepalive))
{
my $ErrMessage = $TA->GetLastError();
--
2.17.1
June 20, 2018
[PATCH] testbot: Retrieve the list of Wine files.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunReconfig.pl | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index fe69fc3b7..d04b78061 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -444,6 +444,16 @@ if ($NewStatus eq "completed")
{
$TAError = "An error occurred while retrieving the test list: ". $TA->GetLastError();
}
+
+ Debug(Elapsed($Start), " Retrieving the list of Wine files '$TaskDir/winefiles.txt'\n");
+ if ($TA->GetFile("latest/winefiles.txt", "$TaskDir/winefiles.txt"))
+ {
+ copy "$TaskDir/winefiles.txt", "$DataDir/latest/winefiles.txt";
+ }
+ elsif (!defined $TAError)
+ {
+ $TAError = "An error occurred while retrieving the list of Wine files: ". $TA->GetLastError();
+ }
}
$TA->Disconnect();
--
2.17.1
June 20, 2018
[PATCH] testbot/WineRun*: Rename the timeout WrapUpAndExit() parameter.
by Francois Gouget
It is a boolean indicating whether the task timed out, not the timeout
value in seconds.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 4 ++--
testbot/bin/WineRunReconfig.pl | 4 ++--
testbot/bin/WineRunTask.pl | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index eab33bc08..1bc6cffbc 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -196,11 +196,11 @@ sub LogTaskError($)
sub WrapUpAndExit($;$$)
{
- my ($Status, $Retry, $Timeout) = @_;
+ my ($Status, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
my $TestFailures;
my $Tries = $Task->TestFailures || 0;
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index e7b447e92..fe69fc3b7 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -195,12 +195,12 @@ sub LogTaskError($)
sub WrapUpAndExit($;$$)
{
- my ($Status, $Retry, $Timeout) = @_;
+ my ($Status, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' :
$Status eq 'completed' ? 'idle' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
my $TestFailures;
my $Tries = $Task->TestFailures || 0;
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 3b0ccbc4a..e10656ed8 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -226,11 +226,11 @@ sub LogTaskError($)
sub WrapUpAndExit($;$$$)
{
- my ($Status, $TestFailures, $Retry, $Timeout) = @_;
+ my ($Status, $TestFailures, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
Debug(Elapsed($Start), " Taking a screenshot\n");
TakeScreenshot($VM, "$TaskDir/screenshot.png");
--
2.17.1
June 20, 2018
[PATCH] testbot/build: Detect patches that impact more than the tests.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 2 +-
testbot/lib/WineTestBot/PatchUtils.pm | 101 ++++++++++++++++----------
2 files changed, 64 insertions(+), 39 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 3fe0e14ea..8318af12a 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -246,7 +246,7 @@ exit(1) if (!$Impacts);
CountCPUs();
-if (!BuildNative())
+if ($Impacts->{WineBuild} and !BuildNative())
{
exit(1);
}
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index 6eb8e3cd8..f83df6087 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -36,6 +36,23 @@ our @EXPORT = qw(GetPatchImpact UpdateWineData);
use WineTestBot::Config;
+# Patches to these paths don't impact the Wine build. So ignore them.
+my $IgnoredPathsRe = join('|',
+ '\.mailmap$',
+ 'ANNOUNCE$',
+ 'AUTHORS$',
+ 'COPYING\.LIB$',
+ 'LICENSE\$',
+ 'LICENSE\.OLD$',
+ 'MAINTAINERS$',
+ 'README$',
+ 'VERSION$',
+ 'documentation/',
+ 'tools/c2man\.pl$',
+ 'tools/winapi/',
+ 'tools/winemaker/',
+);
+
=pod
=over 12
@@ -102,46 +119,54 @@ sub GetTestList()
return $TestList;
}
-sub _AddTest($$$)
+sub _HandleFile($$$)
{
my ($Impacts, $Path, $Change) = @_;
- return if ($Path !~ m~^(dlls|programs)/([^/]+)/tests/([^/\s]+)$~);
- my ($Root, $Module, $File) = ($1, $2, $3);
-
- my $Tests = $Impacts->{Tests};
- if (!$Tests->{$Module})
+ if ($Path =~ m~^(dlls|programs)/([^/]+)/tests/([^/\s]+)$~)
{
- my $ExeBase = ($Root eq "programs") ? "${Module}.exe_test" :
- "${Module}_test";
- $Tests->{$Module} = {
- "Module" => $Module,
- "Path" => "$Root/$Module/tests",
- "ExeBase" => $ExeBase,
- };
- }
+ my ($Root, $Module, $File) = ($1, $2, $3);
+ $Impacts->{TestBuild} = 1;
- # Assume makefile modifications may break the build but not the tests
- if ($File eq "Makefile.in")
- {
- if ($Change eq "new" or $Change eq "rm")
+ my $Tests = $Impacts->{Tests};
+ if (!$Tests->{$Module})
{
- # This adds / removes a directory
- $Impacts->{Makefiles} = 1;
+ my $ExeBase = ($Root eq "programs") ? "${Module}.exe_test" :
+ "${Module}_test";
+ $Tests->{$Module} = {
+ "Module" => $Module,
+ "Path" => "$Root/$Module/tests",
+ "ExeBase" => $ExeBase,
+ };
}
- return;
- }
- return if ($Impacts->{NoUnits});
- if (!$Tests->{$Module}->{Files})
- {
- my $TestList = ( $Impacts->{TestList} ||= GetTestList() );
- foreach my $File (keys %{$TestList->{$Module}})
+ # Assume makefile modifications may break the build but not the tests
+ if ($File eq "Makefile.in")
{
- $Tests->{$Module}->{Files}->{$File} = 0; # not modified
+ if ($Change eq "new" or $Change eq "rm")
+ {
+ # This adds / removes a directory
+ $Impacts->{Makefiles} = 1;
+ }
+ return;
}
+ return if ($Impacts->{NoUnits});
+
+ if (!$Tests->{$Module}->{Files})
+ {
+ my $TestList = ( $Impacts->{TestList} ||= GetTestList() );
+ foreach my $File (keys %{$TestList->{$Module}})
+ {
+ $Tests->{$Module}->{Files}->{$File} = 0; # not modified
+ }
+ }
+ $Tests->{$Module}->{Files}->{$File} = $Change;
+ }
+ else
+ {
+ # Figure out if this patch impacts the Wine build
+ $Impacts->{WineBuild} = 1 if ($Path !~ /^(?:$IgnoredPathsRe)/);
}
- $Tests->{$Module}->{Files}->{$File} = $Change;
}
=pod
@@ -176,8 +201,8 @@ sub GetPatchImpact($;$$)
{
foreach my $File (keys %{$PastInfo->{Files}})
{
- _AddTest($Impacts, "$PastInfo->{Path}/$File",
- $PastInfo->{Files}->{$File} eq "rm" ? "rm" : 0);
+ _HandleFile($Impacts, "$PastInfo->{Path}/$File",
+ $PastInfo->{Files}->{$File} eq "rm" ? "rm" : 0);
}
}
}
@@ -187,33 +212,33 @@ sub GetPatchImpact($;$$)
{
if ($Line =~ m=^--- \w+/(?:aclocal\.m4|configure\.ac)$=)
{
- $Impacts->{Autoconf} = 1;
+ $Impacts->{WineBuild} = $Impacts->{Autoconf} = 1;
}
elsif ($Line =~ m=^--- \w+/configure$=)
{
- $Impacts->{HasConfigure} = 1;
+ $Impacts->{WineBuild} = $Impacts->{HasConfigure} = 1;
}
elsif ($Line =~ m=^--- \w+/tools/make_makefiles$=)
{
- $Impacts->{Makefiles} = 1;
+ $Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
}
elsif ($Line =~ m=^--- /dev/null$=)
{
$Change = "new";
}
- elsif ($Line =~ m~^--- \w+/([^/]+/[^/]+/tests/[^/\s]+)$~)
+ elsif ($Line =~ m~^--- \w+/([^\s]+)$~)
{
$Path = $1;
}
elsif ($Line =~ m~^\+\+\+ /dev/null$~)
{
- _AddTest($Impacts, $Path, "rm") if (defined $Path);
+ _HandleFile($Impacts, $Path, "rm") if (defined $Path);
$Path = undef;
$Change = "";
}
- elsif ($Line =~ m~^\+\+\+ \w+/(\w+/[^/]+/tests/[^/\s]+)$~)
+ elsif ($Line =~ m~^\+\+\+ \w+/([^\s]+)$~)
{
- _AddTest($Impacts, $1, $Change || "modify");
+ _HandleFile($Impacts, $1, $Change || "modify");
$Path = undef;
$Change = "";
}
--
2.17.1
June 20, 2018
[PATCH] testbot: Adjust the reconfig timeout.
by Francois Gouget
$ReconfigTimeout was way overestimated, maybe reflecting a time when
either the TestBot or the Wine dependencies were causing too many files
to be rebuilt.
Note that $BuildTimeout is a bit large too: a patch touching a test
module and a core header would typically only require about 2.5
minutes. But in the unlikely event where that patch touched dozens of
test modules it may still be too short. So $BuildTimeout is left
unchanged.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Config.pm | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/Config.pm b/testbot/lib/WineTestBot/Config.pm
index b7d633db6..66cb813ff 100644
--- a/testbot/lib/WineTestBot/Config.pm
+++ b/testbot/lib/WineTestBot/Config.pm
@@ -97,9 +97,10 @@ $SingleTimeout = 2 * 60;
# How long to let a regular build run before forcibly shutting it down
# (in seconds).
$BuildTimeout = 5 * 60;
-# How long to let a full recompilation run before forcibly shutting it down
-# (in seconds).
-$ReconfigTimeout = 45 * 60;
+# How long to let a reconfig task run before forcibly shutting it down
+# (in seconds). Note that this includes building the native Wine build tools,
+# and the 32 and 64 bit test executables.
+$ReconfigTimeout = (1 + 2 * 5) * 60;
# How much to add to the task timeout to account for file transfers, etc.
$TimeoutMargin = 2 * 60;
# Maximum amount of traces for a test unit.
--
2.17.1
June 20, 2018
[PATCH] testbot: Simplify a loop in PatchUtils::GetPatchImpact().
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/PatchUtils.pm | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index ec609d987..6eb8e3cd8 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -227,10 +227,8 @@ sub GetPatchImpact($;$$)
$Impacts->{ModuleCount} = 0;
$Impacts->{UnitCount} = 0;
- foreach my $Module (keys %{$Impacts->{Tests}})
+ foreach my $TestInfo (values %{$Impacts->{Tests}})
{
- my $TestInfo = $Impacts->{Tests}->{$Module};
-
# For each module, identify modifications to non-C files and helper dlls
my $AllUnits;
foreach my $File (keys %{$TestInfo->{Files}})
--
2.17.1
June 20, 2018
K32EnumDeviceDrivers
by Anthony Lauzon
Hi All,
I've been hacking away at K32EnumDeviceDrivers trying to get it to properly
handle calls, and have made some decent progress that maybe some of you who
are experts can finish. The reason why I am trying to implement
K32EnumDeviceDrivers is that Creative's Emulator X3 crashes when trying to
call it. I've managed to get the app one step closer to launching with
this K32EnumDeviceDrivers implementation, which does in fact enumerate the
devices, and am now stuck on a different error. I hope this patch is of
some utility to you all.
Anthony
June 19, 2018
[PATCH 2/2] winedbg: Suppress all message boxes if ShowCrashDialog is disabled.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
The only message box shown by this function is the aforementioned
'failed to attach to process' error, but in general the user probably
doesn't want any windows to be shown if ShowCrashDialog is disabled.
programs/winedbg/crashdlg.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/programs/winedbg/crashdlg.c b/programs/winedbg/crashdlg.c
index 4e02a4b..5eb3d27 100644
--- a/programs/winedbg/crashdlg.c
+++ b/programs/winedbg/crashdlg.c
@@ -34,13 +34,18 @@
static char *crash_log;
-int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType)
+int msgbox_res_id(HWND hwnd, UINT textid, UINT captionid, UINT type)
{
- WCHAR caption[256];
- WCHAR text[256];
- LoadStringW(GetModuleHandleW(NULL), captionId, caption, sizeof(caption)/sizeof(caption[0]));
- LoadStringW(GetModuleHandleW(NULL), textId, text, sizeof(text)/sizeof(text[0]));
- return MessageBoxW(hwnd, text, caption, uType);
+ if (DBG_IVAR(ShowCrashDialog))
+ {
+ WCHAR caption[256];
+ WCHAR text[256];
+ LoadStringW(GetModuleHandleW(NULL), captionid, caption, ARRAY_SIZE(caption));
+ LoadStringW(GetModuleHandleW(NULL), textid, text, ARRAY_SIZE(text));
+ return MessageBoxW(hwnd, text, caption, type);
+ }
+
+ return IDCANCEL;
}
static WCHAR *get_program_name(HANDLE hProcess)
--
2.7.4
June 19, 2018
[PATCH 1/2] winedbg: Provide a more helpful error message when unable to attach to a process.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
If anyone has suggestions for better wording, feel free to speak.
programs/winedbg/winedbg.rc | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/programs/winedbg/winedbg.rc b/programs/winedbg/winedbg.rc
index 2cfaf9e..7ad7686 100644
--- a/programs/winedbg/winedbg.rc
+++ b/programs/winedbg/winedbg.rc
@@ -34,8 +34,9 @@ END
STRINGTABLE
BEGIN
- IDS_AUTO_CAPTION "Wine program crash"
- IDS_INVALID_PARAMS "Internal errors - invalid parameters received"
+ IDS_AUTO_CAPTION "Program Error"
+ IDS_INVALID_PARAMS "A program on your system has crashed, but WineDbg was \
+ unable to attach to the process to obtain a backtrace."
IDS_UNIDENTIFIED "(unidentified)"
IDS_TEXT_FILES, "Text files (*.txt)"
IDS_ALL_FILES, "All files (*.*)"
--
2.7.4
June 19, 2018
Re: [PATCH 3/6] d3d9/tests: Add test for depth stencil initialization.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39233
Your paranoid android.
=== w1064 (32 bit visual) ===
visual.c:8620: Test failed: Got unexpected color 0x00007580 for quad 2 (different colors).
June 19, 2018
[PATCH 6/6] wined3d: Call wined3d_cs_emit_update_sub_resource() directly in buffer_init().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 4b14d684e542..181be6bbe487 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1325,6 +1325,8 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, usage);
+ struct wined3d_resource *resource = &buffer->resource;
+ struct wined3d_box box;
BOOL dynamic_buffer_ok;
HRESULT hr;
@@ -1346,7 +1348,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
return E_INVALIDARG;
}
- if (FAILED(hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format, WINED3D_MULTISAMPLE_NONE,
+ if (FAILED(hr = resource_init(resource, device, WINED3D_RTYPE_BUFFER, format, WINED3D_MULTISAMPLE_NONE,
0, usage, access, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops)))
{
WARN("Failed to initialize resource, hr %#x.\n", hr);
@@ -1386,7 +1388,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
{
TRACE("Not creating a BO because the buffer is not GPU accessible.\n");
}
- else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
+ else if (!dynamic_buffer_ok && (resource->usage & WINED3DUSAGE_DYNAMIC))
{
TRACE("Not creating a BO because the buffer has dynamic usage and no GL support.\n");
}
@@ -1398,16 +1400,19 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps))))
{
ERR("Out of memory.\n");
- buffer_unload(&buffer->resource);
- resource_cleanup(&buffer->resource);
- wined3d_resource_wait_idle(&buffer->resource);
+ buffer_unload(resource);
+ resource_cleanup(resource);
+ wined3d_resource_wait_idle(resource);
return E_OUTOFMEMORY;
}
buffer->maps_size = 1;
if (data)
- wined3d_device_update_sub_resource(device, &buffer->resource,
- 0, NULL, data->data, data->row_pitch, data->slice_pitch, 0);
+ {
+ wined3d_box_set(&box, 0, 0, resource->size, 1, 0, 1);
+ wined3d_cs_emit_update_sub_resource(device->cs, resource,
+ 0, &box, data->data, data->row_pitch, data->slice_pitch);
+ }
return WINED3D_OK;
}
--
2.16.4
June 19, 2018
[PATCH 5/6] wined3d: Use WINED3D_LOCATION_DISCARDED before initializing buffers with data.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index e06d156c0b3f..4b14d684e542 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1354,7 +1354,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
}
buffer->buffer_type_hint = buffer_type_hint_from_bind_flags(gl_info, bind_flags);
buffer->bind_flags = bind_flags;
- buffer->locations = WINED3D_LOCATION_SYSMEM;
+ buffer->locations = data ? WINED3D_LOCATION_DISCARDED : WINED3D_LOCATION_SYSMEM;
if (!wined3d_resource_allocate_sysmem(&buffer->resource))
return E_OUTOFMEMORY;
--
2.16.4
June 19, 2018
[PATCH 4/6] wined3d: Reduce nesting in texture2d_load_sysmem().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/surface.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 521703314d0c..5502d055c263 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -198,7 +198,6 @@ static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3
else
wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
-
if (src_location == WINED3D_LOCATION_DRAWABLE)
{
required_texture = src_texture;
@@ -1655,21 +1654,18 @@ BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_res
WINED3D_LOCATION_RB_RESOLVED, dst_location);
return TRUE;
}
- else
- {
- if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
- wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
- /* Download the sub-resource to system memory. */
- if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
- {
- wined3d_texture_bind_and_dirtify(texture, context,
- !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
- texture2d_download_data(texture, sub_resource_idx, context, dst_location);
- ++texture->download_count;
+ if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
+ wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
- return TRUE;
- }
+ /* Download the sub-resource to system memory. */
+ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+ {
+ wined3d_texture_bind_and_dirtify(texture, context,
+ !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
+ texture2d_download_data(texture, sub_resource_idx, context, dst_location);
+ ++texture->download_count;
+ return TRUE;
}
if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
--
2.16.4
June 19, 2018
[PATCH 3/6] d3d9/tests: Add test for depth stencil initialization.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d9/tests/visual.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 95982e051556..b36c1890392c 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -211,6 +211,34 @@ static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
return ret;
}
+#define check_rt_color(a, b) check_rt_color_(__LINE__, a, b)
+static void check_rt_color_(unsigned int line, IDirect3DSurface9 *rt, D3DCOLOR expected_color)
+{
+ struct surface_readback rb;
+ D3DSURFACE_DESC desc;
+ unsigned int x, y;
+ D3DCOLOR color;
+ HRESULT hr;
+
+ hr = IDirect3DSurface9_GetDesc(rt, &desc);
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get surface desc, hr %#x.\n", hr);
+
+ get_rt_readback(rt, &rb);
+ for (y = 0; y < desc.Height; ++y)
+ {
+ for (x = 0; x < desc.Width; ++x)
+ {
+ color = get_readback_color(&rb, x, y) & 0x00ffffff;
+ if (color != expected_color)
+ break;
+ }
+ if (color != expected_color)
+ break;
+ }
+ release_surface_readback(&rb);
+ ok_(__FILE__, line)(color == 0x000000ff, "Got unexpected color 0x%08x.\n", color);
+}
+
static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
{
D3DPRESENT_PARAMETERS present_parameters = {0};
@@ -21406,6 +21434,92 @@ done:
DestroyWindow(window);
}
+static void test_depth_stencil_init(void)
+{
+ IDirect3DDevice9 *device;
+ IDirect3DSurface9 *ds[2];
+ IDirect3DSurface9 *rt;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ unsigned int i;
+ HWND window;
+ HRESULT hr;
+
+ static const struct
+ {
+ struct vec3 position;
+ }
+ quad[] =
+ {
+ {{-1.0f, -1.0f, 0.0f}},
+ {{-1.0f, 1.0f, 0.0f}},
+ {{ 1.0f, -1.0f, 0.0f}},
+ {{ 1.0f, 1.0f, 0.0f}},
+ };
+
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create D3D object.\n");
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create D3D device.\n");
+ goto done;
+ }
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ ok(hr == S_OK, "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ ok(hr == S_OK, "Failed to set color arg, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
+ ok(hr == S_OK, "Failed to set FVF, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds[0], NULL);
+ ok(hr == S_OK, "Failed to create depth stencil surface, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds[1]);
+ ok(hr == S_OK, "Failed to get depth stencil surface, hr %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(ds); ++i)
+ {
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds[i]);
+ ok(hr == S_OK, "Failed to set depth stencil surface, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(hr == S_OK, "Failed to begin scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(hr == S_OK, "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(hr == S_OK, "Failed to end scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
+ ok(hr == S_OK, "Failed to get render target, hr %#x.\n", hr);
+ check_rt_color(rt, 0x000000ff);
+ IDirect3DSurface9_Release(rt);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
+
+ IDirect3DSurface9_Release(ds[i]);
+ }
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+
+done:
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
static void test_texture_blending(void)
{
#define STATE_END() {0xffffffff, 0xffffffff}
@@ -24037,6 +24151,7 @@ START_TEST(visual)
test_flip();
test_uninitialized_varyings();
test_multisample_init();
+ test_depth_stencil_init();
test_texture_blending();
test_color_clamping();
test_line_antialiasing_blending();
--
2.16.4
June 19, 2018
[PATCH 2/6] wined3d: Initialize depth/stencil texture data.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
Fixes rendering glitches in Company of Heroes on radeonsi.
---
dlls/wined3d/texture.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 91c703c970fd..c316906a9576 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2802,8 +2802,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
if (wined3d_texture_use_pbo(texture, gl_info))
texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
- if ((desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
- && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
+ if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
|| !wined3d_texture_use_pbo(texture, gl_info))
{
if (!wined3d_resource_allocate_sysmem(&texture->resource))
@@ -2842,8 +2841,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
sub_resource = &texture->sub_resources[i];
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
- if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
- && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
+ if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D)
{
wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM);
wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM);
--
2.16.4
June 19, 2018