die "Invalid attributes for data symbol: $symbol" if $isdata && ($atsign || defined $args);
die "\@funcname without \@4 suffix not recognized: $symbol" if $atsign && !defined $args;
die "Invalid \@$args number: $symbol" if defined $args && ($args<0 || ($args%4));
- if (!$argscdecl) {
+ if (!defined $argscdecl) { # beware: $argscdecl may eq "0"
die "Duplicate symbol: $symbol" if exists $def{$symbol};
}
else {
$args=$argscdecl;
}
$def{$symbol}={
- "type"=>($isdata ? "data" : (!defined $args ? "cdecl" : (!$atsign ? "stdcall" : "fastcall"))),
+ "type"=>($isdata ? "data" : (!defined($args) || defined($argscdecl) ? "cdecl" : (!$atsign ? "stdcall" : "fastcall"))),
(!defined $args ? () : ("args4"=>$args/4)),
};
}
}
die "Symbol not in *.def files: $symbol" if $iswhat ne "undef" && !$def{$symbol};
if ($iswhat eq "pass" || $iswhat eq "wrap") {
- die "args count not fixed up for '$iswhat' type: ".$symbol."[".$def{$symbol}{"type"}."]" if !$def{$symbol}{"args4"};
+ die "args count not fixed up for '$iswhat' type: ".$symbol."[".$def{$symbol}{"type"}."]"
+ if !exists $def{$symbol}{"args4"} && $def{$symbol}{"type"} ne "data"; # beware: {"args"} may ==0
die "'$iswhat' not permitted if <patch> not specified for module on symbol: $symbol" if !$patch{$module};
$def{$symbol}{$iswhat}=1;
}
#include <glib/gmessages.h>
#include <glib/gmacros.h>
-#include <string.h> /* for built-in: strncmp,memmove */
+#include <string.h> /* for built-in: strncmp,memmove,strncpy */
+extern gboolean captive_debug_messages_disabled;
+
HERE
for my $symbol (sort keys(%symbol)) {
next;
}
if ($patch{$symbol{$symbol}} && "data" ne $def->{"type"}) {
- print "static struct captive_ModuleList_patchpoint ${symbol}_patchpoint;\n";
+ # We do not declare it 'static' as we sometimes make 'extern' references to it
+ # such as 'ExInitializeNPagedLookasideList_patchpoint' in libcaptive/ex/lookas.c.
+ print "struct captive_ModuleList_patchpoint ${symbol}_patchpoint;\n";
}
if ("data" eq $def->{"type"}) {
- die "'data' type not pass-able: $symbol" if $def->{"pass"} || $def->{"wrap"};
+ next if $def->{"pass"} || $def->{"wrap"}; # FIXME: export for .so
print "extern void/* ==unknown */ ${symbol};\n";
print "#define ${symbol}_".$def->{"type"}." ${symbol}\n";
next;
}
if ("cdecl" eq $def->{"type"} && !defined $def->{"args4"} && !$def->{"pass"} && !$def->{"wrap"}) {
# g_log(,G_LOG_LEVEL_DEBUG,...) not possible if we do not know the arguments count
- my %forbidden=map(($_=>1),qw(strncmp memmove)); # Prevent: conflicting types for built-in function ...
+ my %forbidden=map(($_=>1),qw(strncmp memmove strncpy)); # Prevent: conflicting types for built-in function ...
print "void/* ==unknown */ ${symbol}(void/* ==unknown */);\n" if !$forbidden{$symbol};
print "#define ${symbol}_".$def->{"type"}." ${symbol}\n";
next;
"\tg_return_val_if_fail(${symbol}_patchpoint.orig_w32_func!=NULL,0);\n",
"\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n",
"\t${symbol}_patchpoint.through_w32_func=TRUE;\n",
- "\tr=(*(${symbol}_t_attrib *)${symbol}_patchpoint.orig_w32_func)(".join(",",@args_in).");\n",
- "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n";
+ "\tr=(*(${symbol}_t_attrib *)${symbol}_patchpoint.orig_w32_func)(".join(",",@args_in).");\n";
+ if (!$def->{"pass"}) {
+ print
+ "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n";
+ }
+ else {
+ print
+ "\tif (!captive_debug_messages_disabled)\n",
+ "\t\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n",
+ "\telse {\n",
+ "\t\tg_assert(${symbol}_patchpoint.through_w32_func==TRUE);\n",
+ "\t\t${symbol}_patchpoint.through_w32_func=FALSE;\n",
+ "\t\t}\n";
+ }
}
else {
print
}
# write function captive_kernel_{exports,patches}()
-for my $functype ("exports","patches") {
+for my $functype ("exports","patches_debug","patches_nondebug") {
print <<"HERE";
gboolean captive_kernel_$functype(void)
HERE
for my $module (sort keys(%module)) {
my $moduleref=$module{$module};
- next if ($functype eq "patches") != defined $patch{$module};
+ next if ($functype=~/^patches/) != defined $patch{$module};
print "\t\terrbool="
- .($functype eq "patches" ? "captive_ModuleList_patch" : "captive_ModuleList_add_builtin")
+ .($functype=~/^patches/ ? "captive_ModuleList_patch" : "captive_ModuleList_add_builtin")
."(\"$module\",\n";
for my $symbol (sort keys(%$moduleref)) {
- next if $functype eq "patches" && !$def{$symbol};
- print "\t\t\t\"$symbol\",&${symbol}_",
- ($def{$symbol}{"type"} || "undef"),
- (($functype ne "patches") ? () : (",".("data" eq $def{$symbol}{"type"} ? "NULL" : "&${symbol}_patchpoint"))),
+ next if $functype=~/^patches/ && !$def{$symbol};
+ (my $symbol_outer=$symbol)=~s/^captive_reactos_//;
+ print "\t\t\t\"$symbol_outer\",",(($functype=~/^patches/ && "data" eq $def{$symbol}{"type"}
+ && ($def{$symbol}{"pass"} || $def{$symbol}{"wrap"})) ? ("NULL")
+ : ("&${symbol}_",($def{$symbol}{"type"} || "undef"))),
+ (($functype!~/^patches/) ? () :
+ (",".("data" eq $def{$symbol}{"type"} ? "NULL,NULL" :
+ ($functype eq "patches_nondebug" && $def{$symbol}{"pass"} ? "&${symbol}_patchpoint,NULL" :
+ "&${symbol}_patchpoint,&${symbol}_patchpoint")))),
",\n";
}
print <<"HERE";
Any function call even inside such module is trapped and redirected for
libcaptive processing even if it is just for debug-dumping of B<pass> type.
-=item (B<module>,B<symbol>,[undef|pass|wrap])
-
-=over
-
-=item ""
+=item (B<module>,B<symbol>)
Name without special attribute declares function fully implemented by GNU/Linux
code. Original W32 binary function will never be called.
You may fully implement function for both E<lt>patchE<gt>ed and
unE<lt>patchE<gt>ed modules.
-=item undef
+=item (B<module>,B<symbol>,undef)
Optional "undef" specifies invocation of a generated stub function displaying
C<g_error()> message.
It is forbidden to "undef" C<DATA> type of items; you have to cope with it.
-=item pass
+=item (B<module>,B<symbol>,pass)
Calls of this function are debug-dumped on its entry/exit but they are fully
left to be solved by W32 binary file being E<lt>patchE<gt>ed.
It is forbidden to specify "pass" for unE<lt>patchE<gt>ed modules.
-=item wrap
+=item (B<module>,B<symbol>,wrap)
Calls of this function are debug-dumped on its entry/exit. Execution is left
to be solved by your GNU/Linux implementation called B<functionname_wrap>.
=back
-=back
-
=begin comment
choose one: