winapi.pm 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. #
  2. # Copyright 1999, 2000, 2001 Patrik Stridvall
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2.1 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Lesser General Public
  15. # License along with this library; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  17. #
  18. package winapi;
  19. use strict;
  20. use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  21. require Exporter;
  22. @ISA = qw(Exporter);
  23. @EXPORT = qw();
  24. @EXPORT_OK = qw($win16api $win32api @winapis);
  25. use vars qw($win16api $win32api @winapis);
  26. use config qw($current_dir $wine_dir $winapi_dir);
  27. use options qw($options);
  28. use output qw($output);
  29. use vars qw($modules);
  30. sub found_shared_internal_function($$);
  31. sub function_external_calling_convention_in_module($$$);
  32. sub function_internal_module($$);
  33. sub is_function_stub_in_module($$$);
  34. sub new($$$);
  35. sub parse_api_file($$);
  36. sub parse_spec_file($$);
  37. sub import(@) {
  38. $Exporter::ExportLevel++;
  39. Exporter::import(@_);
  40. $Exporter::ExportLevel--;
  41. if (defined($modules) && defined($win16api) && defined($win32api)) {
  42. return;
  43. }
  44. require modules;
  45. import modules qw($modules);
  46. my @spec_files16 = $modules->allowed_spec_files16;
  47. $win16api = 'winapi'->new("win16", \@spec_files16);
  48. my @spec_files32 = $modules->allowed_spec_files32;
  49. $win32api = 'winapi'->new("win32", \@spec_files32);
  50. @winapis = ($win16api, $win32api);
  51. for my $internal_name ($win32api->all_internal_functions) {
  52. my $module16 = $win16api->function_internal_module($internal_name);
  53. my $module32 = $win16api->function_internal_module($internal_name);
  54. if(defined($module16) &&
  55. !$win16api->is_function_stub_in_module($module16, $internal_name) &&
  56. !$win32api->is_function_stub_in_module($module32, $internal_name))
  57. {
  58. $win16api->found_shared_internal_function($internal_name);
  59. $win32api->found_shared_internal_function($internal_name);
  60. }
  61. }
  62. }
  63. sub new($$$) {
  64. my $proto = shift;
  65. my $class = ref($proto) || $proto;
  66. my $self = {};
  67. bless ($self, $class);
  68. my $name = \${$self->{NAME}};
  69. my $function_forward = \%{$self->{FUNCTION_FORWARD}};
  70. my $function_internal_name = \%{$self->{FUNCTION_INTERNAL_NAME}};
  71. my $function_module = \%{$self->{FUNCTION_MODULE}};
  72. $$name = shift;
  73. my $refspec_files = shift;
  74. foreach my $file (@$refspec_files) {
  75. $self->parse_spec_file("$wine_dir/$file");
  76. }
  77. $self->parse_api_file("$$name.api");
  78. foreach my $module (sort(keys(%$function_forward))) {
  79. foreach my $external_name (sort(keys(%{$$function_forward{$module}}))) {
  80. (my $forward_module, my $forward_external_name) = @{$$function_forward{$module}{$external_name}};
  81. my $forward_internal_name = $$function_internal_name{$forward_external_name};
  82. if(defined($forward_internal_name)) {
  83. $$function_module{$forward_internal_name} .= " & $module";
  84. }
  85. }
  86. }
  87. return $self;
  88. }
  89. sub win16api() {
  90. return $win16api;
  91. }
  92. sub win32api() {
  93. return $win32api;
  94. }
  95. sub parse_api_file($$) {
  96. my $self = shift;
  97. my $allowed_kind = \%{$self->{ALLOWED_KIND}};
  98. my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
  99. my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
  100. my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
  101. my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
  102. my $type_format = \%{$self->{TYPE_FORMAT}};
  103. my $file = shift;
  104. my $module;
  105. my $kind;
  106. my $format;
  107. my $forbidden = 0;
  108. $output->lazy_progress("$file");
  109. open(IN, "< $winapi_dir/$file") || die "$winapi_dir/$file: $!\n";
  110. $/ = "\n";
  111. my $linenum=0;
  112. while(<IN>) {
  113. $linenum++;
  114. s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
  115. s/^(.*?)\s*#.*$/$1/; # remove comments
  116. /^$/ && next; # skip empty lines
  117. if(/^%%(\S+)$/) {
  118. $module = $1;
  119. $module =~ s/\.dll$//; # FIXME: Kludge
  120. } elsif(!$modules->is_allowed_module($module)) {
  121. # Nothing
  122. } elsif(s/^%(\S+)\s*//) {
  123. $kind = $1;
  124. $format = undef;
  125. $forbidden = 0;
  126. $$allowed_kind{$kind} = 1;
  127. if(/^--forbidden/) {
  128. $forbidden = 1;
  129. } elsif(/^--format=(\".*?\"|\S*)/) {
  130. $format = $1;
  131. $format =~ s/^\"(.*?)\"$/$1/;
  132. }
  133. if(!defined($format)) {
  134. if($kind eq "long") {
  135. $format = "%d|%u|%x|%X|";
  136. $format .= "%hd|%hu|%hx|%hX|";
  137. $format .= "%ld|%lu|%lx|%lX|";
  138. $format .= "%04x|%04X|0x%04x|0x%04X|";
  139. $format .= "%08x|%08X|0x%08x|0x%08X|";
  140. $format .= "%08lx|%08lX|0x%08lx|0x%08lX";
  141. } elsif($kind eq "longlong") {
  142. $format = "%lld";
  143. } elsif($kind eq "ptr") {
  144. $format = "%p";
  145. } elsif($kind eq "segptr") {
  146. $format = "%p";
  147. } elsif($kind eq "str") {
  148. $format = "%p|%s";
  149. } elsif($kind eq "wstr") {
  150. $format = "%p|%s";
  151. } elsif($kind eq "word") {
  152. $format = "%d|%u|%x|%X|";
  153. $format .= "%hd|%hu|%hx|%hX|";
  154. $format .= "%04x|%04X|0x%04x|0x%04X";
  155. } else {
  156. $format = "<unknown>";
  157. }
  158. }
  159. } elsif(defined($kind)) {
  160. my $type = $_;
  161. if ($type =~ /\blong\b/)
  162. {
  163. $output->write("$file:$linenum: type ($type) is not Win64 compatible\n");
  164. }
  165. if(!$forbidden) {
  166. if(defined($module)) {
  167. if($$allowed_modules_unlimited{$type}) {
  168. $output->write("$file:$linenum: type ($type) already specified as an unlimited type\n");
  169. } elsif(!$$allowed_modules{$type}{$module}) {
  170. $$allowed_modules{$type}{$module} = 1;
  171. $$allowed_modules_limited{$type} = 1;
  172. } else {
  173. $output->write("$file:$linenum: type ($type) already specified\n");
  174. }
  175. } else {
  176. $$allowed_modules_unlimited{$type} = 1;
  177. }
  178. } else {
  179. $$allowed_modules_limited{$type} = 1;
  180. }
  181. if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
  182. $output->write("$file:$linenum: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
  183. } else {
  184. $$translate_argument{$type} = $kind;
  185. }
  186. $$type_format{$module}{$type} = $format;
  187. } else {
  188. $output->write("$file:$linenum: file must begin with %<type> statement\n");
  189. exit 1;
  190. }
  191. }
  192. close(IN);
  193. }
  194. sub parse_spec_file($$) {
  195. my $self = shift;
  196. my $function_internal_arguments = \%{$self->{FUNCTION_INTERNAL_ARGUMENTS}};
  197. my $function_external_arguments = \%{$self->{FUNCTION_EXTERNAL_ARGUMENTS}};
  198. my $function_internal_ordinal = \%{$self->{FUNCTION_INTERNAL_ORDINAL}};
  199. my $function_external_ordinal = \%{$self->{FUNCTION_EXTERNAL_ORDINAL}};
  200. my $function_internal_calling_convention = \%{$self->{FUNCTION_INTERNAL_CALLING_CONVENTION}};
  201. my $function_external_calling_convention = \%{$self->{FUNCTION_EXTERNAL_CALLING_CONVENTION}};
  202. my $function_internal_name = \%{$self->{FUNCTION_INTERNAL_NAME}};
  203. my $function_external_name = \%{$self->{FUNCTION_EXTERNAL_NAME}};
  204. my $function_forward = \%{$self->{FUNCTION_FORWARD}};
  205. my $function_internal_module = \%{$self->{FUNCTION_INTERNAL_MODULE}};
  206. my $function_external_module = \%{$self->{FUNCTION_EXTERNAL_MODULE}};
  207. my $function_wine_extension = \%{$self->{FUNCTION_WINE_EXTENSION}};
  208. my $modules = \%{$self->{MODULES}};
  209. my $module_files = \%{$self->{MODULE_FILES}};
  210. my $module_external_calling_convention = \%{$self->{MODULE_EXTERNAL_CALLING_CONVENTION}};
  211. my $file = shift;
  212. $file =~ s%^\./%%;
  213. my %ordinals;
  214. my $module;
  215. my $wine_extension = 0;
  216. $output->lazy_progress("$file");
  217. $module = $file;
  218. $module =~ s/^.*?([^\/]*)\.spec$/$1/;
  219. open(IN, "< $file") || die "$file: $!\n";
  220. $/ = "\n";
  221. my $header = 1;
  222. my $lookahead = 0;
  223. while($lookahead || defined($_ = <IN>)) {
  224. $lookahead = 0;
  225. s/^\s*(.*?)\s*$/$1/;
  226. if(s/^(.*?)\s*\#\s*(.*)\s*$/$1/) {
  227. my $comment = $2;
  228. if ($comment =~ /^Wine/i) { # FIXME: Kludge
  229. $wine_extension = 1;
  230. }
  231. }
  232. /^$/ && next;
  233. if($header) {
  234. if(/^\d+|@/) { $header = 0; $lookahead = 1; }
  235. next;
  236. }
  237. my $ordinal;
  238. my $ARCHES="arm|arm64|i386|powerpc|win32|win64|x86_64";
  239. if(/^(\d+|@)\s+
  240. (cdecl|pascal|stdcall|varargs|thiscall)\s+
  241. ((?:(?:-arch=(?:$ARCHES)(?:,(?:$ARCHES))*|-noname|-norelay|-ordinal|-i386|-ret16|-ret64|-register|-interrupt|-private)\s+)*)(\S+)\s*\(\s*(.*?)\s*\)\s*(\S*)$/x)
  242. {
  243. my $calling_convention = $2;
  244. my $flags = $3;
  245. my $external_name = $4;
  246. my $arguments = $5;
  247. my $internal_name = $6;
  248. $ordinal = $1;
  249. $flags =~ s/\s+/ /g;
  250. if (!$internal_name)
  251. {
  252. $internal_name = ($flags =~ /-register/ ? "__regs_" : "") . $external_name;
  253. }
  254. if($flags =~ /-noname/) {
  255. # $external_name = "@";
  256. }
  257. if($flags =~ /(?:-register|-interrupt)/) {
  258. if($arguments) { $arguments .= " "; }
  259. $arguments .= "ptr";
  260. $calling_convention .= " -register";
  261. }
  262. if($flags =~ /(?:-i386)/) {
  263. $calling_convention .= " -i386";
  264. }
  265. if ($internal_name =~ /^(.*?)\.(.*?)$/) {
  266. my $forward_module = lc($1);
  267. my $forward_name = $2;
  268. $calling_convention = "forward";
  269. $$function_forward{$module}{$external_name} = [$forward_module, $forward_name];
  270. }
  271. if($external_name ne "@") {
  272. $$module_external_calling_convention{$module}{$external_name} = $calling_convention;
  273. } else {
  274. $$module_external_calling_convention{$module}{"\@$ordinal"} = $calling_convention;
  275. }
  276. if(!$$function_internal_name{$external_name}) {
  277. $$function_internal_name{$external_name} = $internal_name;
  278. } else {
  279. $$function_internal_name{$external_name} .= " & $internal_name";
  280. }
  281. if(!$$function_external_name{$internal_name}) {
  282. $$function_external_name{$internal_name} = $external_name;
  283. } else {
  284. $$function_external_name{$internal_name} .= " & $external_name";
  285. }
  286. $$function_internal_arguments{$internal_name} = $arguments;
  287. $$function_external_arguments{$external_name} = $arguments;
  288. if(!$$function_internal_ordinal{$internal_name}) {
  289. $$function_internal_ordinal{$internal_name} = $ordinal;
  290. } else {
  291. $$function_internal_ordinal{$internal_name} .= " & $ordinal";
  292. }
  293. if(!$$function_external_ordinal{$external_name}) {
  294. $$function_external_ordinal{$external_name} = $ordinal;
  295. } else {
  296. $$function_external_ordinal{$external_name} .= " & $ordinal";
  297. }
  298. $$function_internal_calling_convention{$internal_name} = $calling_convention;
  299. $$function_external_calling_convention{$external_name} = $calling_convention;
  300. if(!$$function_internal_module{$internal_name}) {
  301. $$function_internal_module{$internal_name} = "$module";
  302. } else {
  303. $$function_internal_module{$internal_name} .= " & $module";
  304. }
  305. if(!$$function_external_module{$external_name}) {
  306. $$function_external_module{$external_name} = "$module";
  307. } else {
  308. $$function_external_module{$external_name} .= " & $module";
  309. }
  310. $$function_wine_extension{$module}{$external_name} = $wine_extension;
  311. if(0 && $options->spec_mismatch) {
  312. if($external_name eq "@") {
  313. if($internal_name !~ /^\U$module\E_$ordinal$/) {
  314. $output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
  315. }
  316. } else {
  317. my $name = $external_name;
  318. my $name1 = $name;
  319. $name1 =~ s/^Zw/Nt/;
  320. my $name2 = $name;
  321. $name2 =~ s/^(?:_|Rtl|k32|K32)//;
  322. my $name3 = $name;
  323. $name3 =~ s/^INT_Int[0-9a-f]{2}Handler$/BUILTIN_DefaultIntHandler/;
  324. my $name4 = $name;
  325. $name4 =~ s/^(VxDCall)\d$/$1/;
  326. # FIXME: This special case is because of a very ugly kludge that should be fixed IMHO
  327. my $name5 = $name;
  328. $name5 =~ s/^(.*?16)_(.*?)$/$1_fn$2/;
  329. if(uc($internal_name) ne uc($external_name) &&
  330. $internal_name !~ /(\Q$name\E|\Q$name1\E|\Q$name2\E|\Q$name3\E|\Q$name4\E|\Q$name5\E)/)
  331. {
  332. $output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
  333. }
  334. }
  335. }
  336. } elsif(/^(\d+|@)\s+stub(?:\s+(-arch=(?:$ARCHES)(?:,(?:$ARCHES))*|-noname|-norelay|-ordinal|-i386|-ret16|-ret64|-private))*\s+(\S+?)\s*(\(\s*(.*?)\s*\))?$/) {
  337. $ordinal = $1;
  338. my $flags = $2;
  339. my $external_name = $3;
  340. $flags = "" if !defined($flags);
  341. if($flags =~ /-noname/) {
  342. # $external_name = "@";
  343. }
  344. my $internal_name = $external_name;
  345. if ($external_name ne "@") {
  346. $$module_external_calling_convention{$module}{$external_name} = "stub";
  347. } else {
  348. $$module_external_calling_convention{$module}{"\@$ordinal"} = "stub";
  349. }
  350. if(!$$function_internal_name{$external_name}) {
  351. $$function_internal_name{$external_name} = $internal_name;
  352. } else {
  353. $$function_internal_name{$external_name} .= " & $internal_name";
  354. }
  355. if(!$$function_external_name{$internal_name}) {
  356. $$function_external_name{$internal_name} = $external_name;
  357. } else {
  358. $$function_external_name{$internal_name} .= " & $external_name";
  359. }
  360. if(!$$function_internal_ordinal{$internal_name}) {
  361. $$function_internal_ordinal{$internal_name} = $ordinal;
  362. } else {
  363. $$function_internal_ordinal{$internal_name} .= " & $ordinal";
  364. }
  365. if(!$$function_external_ordinal{$external_name}) {
  366. $$function_external_ordinal{$external_name} = $ordinal;
  367. } else {
  368. $$function_external_ordinal{$external_name} .= " & $ordinal";
  369. }
  370. if(!$$function_internal_module{$internal_name}) {
  371. $$function_internal_module{$internal_name} = "$module";
  372. } else { # if($$function_internal_module{$internal_name} !~ /$module/) {
  373. $$function_internal_module{$internal_name} .= " & $module";
  374. }
  375. if(!$$function_external_module{$external_name}) {
  376. $$function_external_module{$external_name} = "$module";
  377. } else { # if($$function_external_module{$external_name} !~ /$module/) {
  378. $$function_external_module{$external_name} .= " & $module";
  379. }
  380. } elsif(/^(\d+|@)\s+extern(?:\s+(?:-arch=(?:$ARCHES)(?:,(?:$ARCHES))*|-noname|-norelay|-ordinal|-i386|-ret16|-ret64))*\s+(\S+)\s*(\S*)$/) {
  381. $ordinal = $1;
  382. my $external_name = $2;
  383. my $internal_name = $3;
  384. $internal_name = $external_name if !$internal_name;
  385. if ($external_name ne "@") {
  386. $$module_external_calling_convention{$module}{$external_name} = "extern";
  387. } else {
  388. $$module_external_calling_convention{$module}{"\@$ordinal"} = "extern";
  389. }
  390. } elsif(/^(?:\d+|@)\s+(?:equate|variable)/) {
  391. # ignore
  392. } else {
  393. my $next_line = <IN>;
  394. if(!defined($next_line) || $next_line =~ /^\s*\d|@/) {
  395. die "$file: $.: syntax error: '$_'\n";
  396. } else {
  397. $_ .= $next_line;
  398. $lookahead = 1;
  399. }
  400. }
  401. if(defined($ordinal)) {
  402. if($ordinal ne "@" && $ordinals{$ordinal}) {
  403. $output->write("$file: ordinal redefined: $_\n");
  404. }
  405. $ordinals{$ordinal}++;
  406. }
  407. }
  408. close(IN);
  409. $$modules{$module}++;
  410. $$module_files{$module} = $file;
  411. }
  412. sub name($) {
  413. my $self = shift;
  414. my $name = \${$self->{NAME}};
  415. return $$name;
  416. }
  417. sub is_allowed_kind($$) {
  418. my $self = shift;
  419. my $allowed_kind = \%{$self->{ALLOWED_KIND}};
  420. my $kind = shift;
  421. if(defined($kind)) {
  422. return $$allowed_kind{$kind};
  423. } else {
  424. return 0;
  425. }
  426. }
  427. sub allow_kind($$) {
  428. my $self = shift;
  429. my $allowed_kind = \%{$self->{ALLOWED_KIND}};
  430. my $kind = shift;
  431. $$allowed_kind{$kind}++;
  432. }
  433. sub is_limited_type($$) {
  434. my $self = shift;
  435. my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
  436. my $type = shift;
  437. return $$allowed_modules_limited{$type};
  438. }
  439. sub is_allowed_type_in_module($$) {
  440. my $self = shift;
  441. my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
  442. my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
  443. my $type = shift;
  444. my @modules = split(/ \& /, shift);
  445. if(!$$allowed_modules_limited{$type}) { return 1; }
  446. foreach my $module (@modules) {
  447. if($$allowed_modules{$type}{$module}) { return 1; }
  448. }
  449. return 0;
  450. }
  451. sub allow_type_in_module($$) {
  452. my $self = shift;
  453. my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
  454. my $type = shift;
  455. my @modules = split(/ \& /, shift);
  456. foreach my $module (@modules) {
  457. $$allowed_modules{$type}{$module}++;
  458. }
  459. }
  460. sub type_used_in_module($$) {
  461. my $self = shift;
  462. my $used_modules = \%{$self->{USED_MODULES}};
  463. my $type = shift;
  464. my @modules = split(/ \& /, shift);
  465. foreach my $module (@modules) {
  466. $$used_modules{$type}{$module} = 1;
  467. }
  468. return ();
  469. }
  470. sub types_not_used($) {
  471. my $self = shift;
  472. my $used_modules = \%{$self->{USED_MODULES}};
  473. my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
  474. my $not_used;
  475. foreach my $type (sort(keys(%$allowed_modules))) {
  476. foreach my $module (sort(keys(%{$$allowed_modules{$type}}))) {
  477. if(!$$used_modules{$type}{$module}) {
  478. $$not_used{$module}{$type} = 1;
  479. }
  480. }
  481. }
  482. return $not_used;
  483. }
  484. sub types_unlimited_used_in_modules($) {
  485. my $self = shift;
  486. my $used_modules = \%{$self->{USED_MODULES}};
  487. my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
  488. my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
  489. my $used_types;
  490. foreach my $type (sort(keys(%$allowed_modules_unlimited))) {
  491. my $count = 0;
  492. my @modules = ();
  493. foreach my $module (sort(keys(%{$$used_modules{$type}}))) {
  494. $count++;
  495. push @modules, $module;
  496. }
  497. if($count) {
  498. foreach my $module (@modules) {
  499. $$used_types{$type}{$module} = 1;
  500. }
  501. }
  502. }
  503. return $used_types;
  504. }
  505. sub translate_argument($$) {
  506. my $self = shift;
  507. my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
  508. my $type = shift;
  509. return $$translate_argument{$type};
  510. }
  511. sub declare_argument($$$) {
  512. my $self = shift;
  513. my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
  514. my $type = shift;
  515. my $kind = shift;
  516. $$translate_argument{$type} = $kind;
  517. }
  518. sub all_declared_types($) {
  519. my $self = shift;
  520. my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
  521. return sort(keys(%$translate_argument));
  522. }
  523. sub is_allowed_type_format($$$$) {
  524. my $self = shift;
  525. my $type_format = \%{$self->{TYPE_FORMAT}};
  526. my $module = shift;
  527. my $type = shift;
  528. my $format = shift;
  529. my $formats;
  530. if(defined($module) && defined($type)) {
  531. local $_;
  532. foreach (split(/ & /, $module)) {
  533. if(defined($formats)) {
  534. $formats .= "|";
  535. } else {
  536. $formats = "";
  537. }
  538. if(defined($$type_format{$_}{$type})) {
  539. $formats .= $$type_format{$_}{$type};
  540. }
  541. }
  542. }
  543. if(defined($formats)) {
  544. local $_;
  545. foreach (split(/\|/, $formats)) {
  546. if($_ eq $format) {
  547. return 1;
  548. }
  549. }
  550. }
  551. return 0;
  552. }
  553. sub all_modules($) {
  554. my $self = shift;
  555. my $modules = \%{$self->{MODULES}};
  556. return sort(keys(%$modules));
  557. }
  558. sub is_module($$) {
  559. my $self = shift;
  560. my $modules = \%{$self->{MODULES}};
  561. my $name = shift;
  562. return $$modules{$name};
  563. }
  564. sub module_file($$) {
  565. my $self = shift;
  566. my $module = shift;
  567. my $module_files = \%{$self->{MODULE_FILES}};
  568. return $$module_files{$module};
  569. }
  570. sub all_internal_functions($) {
  571. my $self = shift;
  572. my $function_internal_calling_convention = \%{$self->{FUNCTION_INTERNAL_CALLING_CONVENTION}};
  573. return sort(keys(%$function_internal_calling_convention));
  574. }
  575. sub all_internal_functions_in_module($$) {
  576. my $self = shift;
  577. my $function_internal_calling_convention = \%{$self->{FUNCTION_INTERNAL_CALLING_CONVENTION}};
  578. my $function_internal_module = \%{$self->{FUNCTION_INTERNAL_MODULE}};
  579. my $module = shift;
  580. my @names;
  581. foreach my $name (keys(%$function_internal_calling_convention)) {
  582. if($$function_internal_module{$name} eq $module) {
  583. push @names, $name;
  584. }
  585. }
  586. return sort(@names);
  587. }
  588. sub all_external_functions($) {
  589. my $self = shift;
  590. my $function_external_name = \%{$self->{FUNCTION_EXTERNAL_NAME}};
  591. return sort(keys(%$function_external_name));
  592. }
  593. sub all_external_functions_in_module($$) {
  594. my $self = shift;
  595. my $function_external_name = \%{$self->{FUNCTION_EXTERNAL_NAME}};
  596. my $function_external_module = \%{$self->{FUNCTION_EXTERNAL_MODULE}};
  597. my $module = shift;
  598. my @names;
  599. foreach my $name (keys(%$function_external_name)) {
  600. if($$function_external_module{$name} eq $module) {
  601. push @names, $name;
  602. }
  603. }
  604. return sort(@names);
  605. }
  606. sub all_functions_in_module($$) {
  607. my $self = shift;
  608. my $module_external_calling_convention = \%{$self->{MODULE_EXTERNAL_CALLING_CONVENTION}};
  609. my $module = shift;
  610. return sort(keys(%{$$module_external_calling_convention{$module}}));
  611. }
  612. sub all_broken_forwards($) {
  613. my $self = shift;
  614. my $function_forward = \%{$self->{FUNCTION_FORWARD}};
  615. my @broken_forwards = ();
  616. foreach my $module (sort(keys(%$function_forward))) {
  617. foreach my $external_name (sort(keys(%{$$function_forward{$module}}))) {
  618. (my $forward_module, my $forward_external_name) = @{$$function_forward{$module}{$external_name}};
  619. my $forward_external_calling_convention =
  620. $self->function_external_calling_convention_in_module($forward_module, $forward_external_name);
  621. if(!defined($forward_external_calling_convention)) {
  622. push @broken_forwards, [$module, $external_name, $forward_module, $forward_external_name];
  623. }
  624. }
  625. }
  626. return @broken_forwards;
  627. }
  628. sub function_internal_ordinal($$) {
  629. my $self = shift;
  630. my $function_internal_ordinal = \%{$self->{FUNCTION_INTERNAL_ORDINAL}};
  631. my $name = shift;
  632. return $$function_internal_ordinal{$name};
  633. }
  634. sub function_external_ordinal($$) {
  635. my $self = shift;
  636. my $function_external_ordinal = \%{$self->{FUNCTION_EXTERNAL_ORDINAL}};
  637. my $name = shift;
  638. return $$function_external_ordinal{$name};
  639. }
  640. sub function_internal_calling_convention($$) {
  641. my $self = shift;
  642. my $function_internal_calling_convention = \%{$self->{FUNCTION_INTERNAL_CALLING_CONVENTION}};
  643. my $name = shift;
  644. return $$function_internal_calling_convention{$name};
  645. }
  646. sub function_external_calling_convention($$) {
  647. my $self = shift;
  648. my $function_external_calling_convention = \%{$self->{FUNCTION_EXTERNAL_CALLING_CONVENTION}};
  649. my $name = shift;
  650. return $$function_external_calling_convention{$name};
  651. }
  652. sub function_external_calling_convention_in_module($$$) {
  653. my $self = shift;
  654. my $module_external_calling_convention = \%{$self->{MODULE_EXTERNAL_CALLING_CONVENTION}};
  655. my $module = shift;
  656. my $name = shift;
  657. return $$module_external_calling_convention{$module}{$name};
  658. }
  659. sub function_internal_name($$) {
  660. my $self = shift;
  661. my $function_internal_name = \%{$self->{FUNCTION_INTERNAL_NAME}};
  662. my $name = shift;
  663. return $$function_internal_name{$name};
  664. }
  665. sub function_external_name($$) {
  666. my $self = shift;
  667. my $function_external_name = \%{$self->{FUNCTION_EXTERNAL_NAME}};
  668. my $name = shift;
  669. return $$function_external_name{$name};
  670. }
  671. sub function_forward_final_destination($$$) {
  672. my $self = shift;
  673. my $function_forward = \%{$self->{FUNCTION_FORWARD}};
  674. my $module = shift;
  675. my $name = shift;
  676. my $forward_module = $module;
  677. my $forward_name = $name;
  678. while(defined(my $forward = $$function_forward{$forward_module}{$forward_name})) {
  679. ($forward_module, $forward_name) = @$forward;
  680. }
  681. return ($forward_module, $forward_name);
  682. }
  683. sub is_function($$) {
  684. my $self = shift;
  685. my $function_internal_calling_convention = \%{$self->{FUNCTION_INTERNAL_CALLING_CONVENTION}};
  686. my $name = shift;
  687. return $$function_internal_calling_convention{$name};
  688. }
  689. sub all_shared_internal_functions($$) {
  690. my $self = shift;
  691. my $function_shared = \%{$self->{FUNCTION_SHARED}};
  692. return sort(keys(%$function_shared));
  693. }
  694. sub is_shared_internal_function($$) {
  695. my $self = shift;
  696. my $function_shared = \%{$self->{FUNCTION_SHARED}};
  697. my $name = shift;
  698. return $$function_shared{$name};
  699. }
  700. sub found_shared_internal_function($$) {
  701. my $self = shift;
  702. my $function_shared = \%{$self->{FUNCTION_SHARED}};
  703. my $name = shift;
  704. $$function_shared{$name} = 1;
  705. }
  706. sub function_internal_arguments($$) {
  707. my $self = shift;
  708. my $function_internal_arguments = \%{$self->{FUNCTION_INTERNAL_ARGUMENTS}};
  709. my $name = shift;
  710. return $$function_internal_arguments{$name};
  711. }
  712. sub function_external_arguments($$) {
  713. my $self = shift;
  714. my $function_external_arguments = \%{$self->{FUNCTION_EXTERNAL_ARGUMENTS}};
  715. my $name = shift;
  716. return $$function_external_arguments{$name};
  717. }
  718. sub function_internal_module($$) {
  719. my $self = shift;
  720. my $function_internal_module = \%{$self->{FUNCTION_INTERNAL_MODULE}};
  721. my $name = shift;
  722. return $$function_internal_module{$name};
  723. }
  724. sub function_external_module($$) {
  725. my $self = shift;
  726. my $function_external_module = \%{$self->{FUNCTION_EXTERNAL_MODULE}};
  727. my $name = shift;
  728. return $$function_external_module{$name};
  729. }
  730. sub function_wine_extension($$$) {
  731. my $self = shift;
  732. my $function_wine_extension = \%{$self->{FUNCTION_WINE_EXTENSION}};
  733. my $module = shift;
  734. my $name = shift;
  735. return $$function_wine_extension{$module}{$name};
  736. }
  737. sub is_function_stub($$$) {
  738. my $self = shift;
  739. my $module_external_calling_convention = \%{$self->{MODULE_EXTERNAL_CALLING_CONVENTION}};
  740. my $module = shift;
  741. my $name = shift;
  742. if($$module_external_calling_convention{$module}{$name} eq "stub") {
  743. return 1;
  744. }
  745. return 0;
  746. }
  747. sub is_function_stub_in_module($$$) {
  748. my $self = shift;
  749. my $module_external_calling_convention = \%{$self->{MODULE_EXTERNAL_CALLING_CONVENTION}};
  750. my $module = shift;
  751. my $name = shift;
  752. if(!defined($$module_external_calling_convention{$module}{$name})) {
  753. return 0;
  754. }
  755. return $$module_external_calling_convention{$module}{$name} eq "stub";
  756. }
  757. ########################################################################
  758. # class methods
  759. #
  760. sub _get_all_module_internal_ordinal($$) {
  761. my $winapi = shift;
  762. my $internal_name = shift;
  763. my @entries = ();
  764. my @name = (); {
  765. my $name = $winapi->function_external_name($internal_name);
  766. if(defined($name)) {
  767. @name = split(/ & /, $name);
  768. }
  769. }
  770. my @module = (); {
  771. my $module = $winapi->function_internal_module($internal_name);
  772. if(defined($module)) {
  773. @module = split(/ & /, $module);
  774. }
  775. }
  776. my @ordinal = (); {
  777. my $ordinal = $winapi->function_internal_ordinal($internal_name);
  778. if(defined($ordinal)) {
  779. @ordinal = split(/ & /, $ordinal);
  780. }
  781. }
  782. my $name;
  783. my $module;
  784. my $ordinal;
  785. while(defined($name = shift @name) &&
  786. defined($module = shift @module) &&
  787. defined($ordinal = shift @ordinal))
  788. {
  789. push @entries, [$name, $module, $ordinal];
  790. }
  791. return @entries;
  792. }
  793. sub get_all_module_internal_ordinal16($) {
  794. return _get_all_module_internal_ordinal($win16api, $_[0]);
  795. }
  796. sub get_all_module_internal_ordinal32($) {
  797. return _get_all_module_internal_ordinal($win32api, $_[0]);
  798. }
  799. sub get_all_module_internal_ordinal($) {
  800. my @entries = ();
  801. foreach my $winapi (@winapis) {
  802. push @entries, _get_all_module_internal_ordinal($winapi, $_[0]);
  803. }
  804. return @entries;
  805. }
  806. sub _get_all_module_external_ordinal($$) {
  807. my $winapi = shift;
  808. my $external_name = shift;
  809. my @entries = ();
  810. my @name = (); {
  811. my $name = $winapi->function_internal_name($external_name);
  812. if(defined($name)) {
  813. @name = split(/ & /, $name);
  814. }
  815. }
  816. my @module = (); {
  817. my $module = $winapi->function_external_module($external_name);
  818. if(defined($module)) {
  819. @module = split(/ & /, $module);
  820. }
  821. }
  822. my @ordinal = (); {
  823. my $ordinal = $winapi->function_external_ordinal($external_name);
  824. if(defined($ordinal)) {
  825. @ordinal = split(/ & /, $ordinal);
  826. }
  827. }
  828. my $name;
  829. my $module;
  830. my $ordinal;
  831. while(defined($name = shift @name) &&
  832. defined($module = shift @module) &&
  833. defined($ordinal = shift @ordinal))
  834. {
  835. push @entries, [$name, $module, $ordinal];
  836. }
  837. return @entries;
  838. }
  839. sub get_all_module_external_ordinal16($) {
  840. return _get_all_module_external_ordinal($win16api, $_[0]);
  841. }
  842. sub get_all_module_external_ordinal32($) {
  843. return _get_all_module_external_ordinal($win32api, $_[0]);
  844. }
  845. sub get_all_module_external_ordinal($) {
  846. my @entries = ();
  847. foreach my $winapi (@winapis) {
  848. push @entries, _get_all_module_external_ordinal($winapi, $_[0]);
  849. }
  850. return @entries;
  851. }
  852. 1;