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