1#!/usr/bin/env perl 2 3################################################### 4# package to parse IDL files and generate code for 5# rpc functions in Samba 6# Copyright tridge@samba.org 2000-2003 7# Copyright jelmer@samba.org 2005-2007 8# released under the GNU GPL 9 10=pod 11 12=head1 NAME 13 14pidl - An IDL compiler written in Perl 15 16=head1 SYNOPSIS 17 18pidl --help 19 20pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--python[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [--typelib=[OUTPUT]] [<idlfile>.idl]... 21 22=head1 DESCRIPTION 23 24pidl is an IDL compiler written in Perl that aims to be somewhat 25compatible with the midl compiler. IDL is short for 26"Interface Definition Language". 27 28pidl can generate stubs for DCE/RPC server code, DCE/RPC 29client code and Wireshark dissectors for DCE/RPC traffic. 30 31IDL compilers like pidl take a description 32of an interface as their input and use it to generate C 33(though support for other languages may be added later) code that 34can use these interfaces, pretty print data sent 35using these interfaces, or even generate Wireshark 36dissectors that can parse data sent over the 37wire by these interfaces. 38 39pidl takes IDL files in the same format as is used by midl, 40converts it to a .pidl file (which contains pidl's internal representation of the interface) and can then generate whatever output you need. 41.pidl files should be used for debugging purposes only. Write your 42interface definitions in .idl format. 43 44The goal of pidl is to implement a IDL compiler that can be used 45while developing the RPC subsystem in Samba (for 46both marshalling/unmarshalling and debugging purposes). 47 48=head1 OPTIONS 49 50=over 4 51 52=item I<--help> 53 54Show list of available options. 55 56=item I<--version> 57 58Show pidl version 59 60=item I<--outputdir OUTNAME> 61 62Write output files to the specified directory. Defaults to the current 63directory. 64 65=item I<--includedir DIR> 66 67Add DIR to the search path used by the preprocessor. This option can be 68specified multiple times. 69 70=item I<--parse-idl-tree> 71 72Read internal tree structure from input files rather 73than assuming they contain IDL. 74 75=item I<--dump-idl> 76 77Generate a new IDL file. File will be named OUTNAME.idl. 78 79=item I<--header> 80 81Generate a C header file for the specified interface. Filename defaults to OUTNAME.h. 82 83=item I<--ndr-parser> 84 85Generate a C file and C header containing NDR parsers. The filename for 86the parser defaults to ndr_OUTNAME.c. The header filename will be the 87parser filename with the extension changed from .c to .h. 88 89=item I<--tdr-parser> 90 91Generate a C file and C header containing TDR parsers. The filename for 92the parser defaults to tdr_OUTNAME.c. The header filename will be the 93parser filename with the extension changed from .c to .h. 94 95=item I<--typelib> 96 97Write type information to the specified file. 98 99=item I<--server> 100 101Generate boilerplate for the RPC server that implements 102the interface. Filename defaults to ndr_OUTNAME_s.c. 103 104=item I<--template> 105 106Generate stubs for a RPC server that implements the interface. Output will 107be written to stdout. 108 109=item I<--ws-parser> 110 111Generate an Wireshark dissector (in C) and header file. The dissector filename 112defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to 113packet-dcerpc-OUTNAME.h. 114 115Pidl will read additional data from an Wireshark conformance file if present. 116Such a file should have the same location as the IDL file but with the 117extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance> 118for details on the format of this file. 119 120=item I<--diff> 121 122Parse an IDL file, generate a new IDL file based on the internal data 123structures and see if there are any differences with the original IDL file. 124Useful for debugging pidl. 125 126=item I<--dump-idl-tree> 127 128Tell pidl to dump the internal tree representation of an IDL 129file the to disk. Useful for debugging pidl. 130 131=item I<--dump-ndr-tree> 132 133Tell pidl to dump the internal NDR information tree it generated 134from the IDL file to disk. Useful for debugging pidl. 135 136=item I<--samba3-ndr-client> 137 138Generate client calls for Samba3, to be placed in rpc_client/. Instead of 139calling out to the code in Samba3's rpc_parse/, this will call out to 140Samba4's NDR code instead. 141 142=item I<--samba3-ndr-server> 143 144Generate server calls for Samba3, to be placed in rpc_server/. Instead of 145calling out to the code in Samba3's rpc_parse/, this will call out to 146Samba4's NDR code instead. 147 148=back 149 150=head1 IDL SYNTAX 151 152IDL files are always preprocessed using the C preprocessor. 153 154Pretty much everything in an interface (the interface itself, functions, 155parameters) can have attributes (or properties whatever name you give them). 156Attributes always prepend the element they apply to and are surrounded 157by square brackets ([]). Multiple attributes are separated by comma's; 158arguments to attributes are specified between parentheses. 159 160See the section COMPATIBILITY for the list of attributes that 161pidl supports. 162 163C-style comments can be used. 164 165=head2 CONFORMANT ARRAYS 166 167A conformant array is one with that ends in [*] or []. The strange 168things about conformant arrays are that they can only appear as the last 169element of a structure (unless there is a pointer to the conformant array, 170of course) and the array size appears before the structure itself on the wire. 171 172So, in this example: 173 174 typedef struct { 175 long abc; 176 long count; 177 long foo; 178 [size_is(count)] long s[*]; 179 } Struct1; 180 181it appears like this: 182 183 [size_is] [abc] [count] [foo] [s...] 184 185the first [size_is] field is the allocation size of the array, and 186occurs before the array elements and even before the structure 187alignment. 188 189Note that size_is() can refer to a constant, but that doesn't change 190the wire representation. It does not make the array a fixed array. 191 192midl.exe would write the above array as the following C header: 193 194 typedef struct { 195 long abc; 196 long count; 197 long foo; 198 long s[1]; 199 } Struct1; 200 201pidl takes a different approach, and writes it like this: 202 203 typedef struct { 204 long abc; 205 long count; 206 long foo; 207 long *s; 208 } Struct1; 209 210=head2 VARYING ARRAYS 211 212A varying array looks like this: 213 214 typedef struct { 215 long abc; 216 long count; 217 long foo; 218 [size_is(count)] long *s; 219 } Struct1; 220 221This will look like this on the wire: 222 223 [abc] [count] [foo] [PTR_s] [count] [s...] 224 225=head2 FIXED ARRAYS 226 227A fixed array looks like this: 228 229 typedef struct { 230 long s[10]; 231 } Struct1; 232 233The NDR representation looks just like 10 separate long 234declarations. The array size is not encoded on the wire. 235 236pidl also supports "inline" arrays, which are not part of the IDL/NDR 237standard. These are declared like this: 238 239 typedef struct { 240 uint32 foo; 241 uint32 count; 242 uint32 bar; 243 long s[count]; 244 } Struct1; 245 246This appears like this: 247 248 [foo] [count] [bar] [s...] 249 250Fixed arrays are an extension added to support some of the strange 251embedded structures in security descriptors and spoolss. 252 253This section is by no means complete. See the OpenGroup and MSDN 254 documentation for additional information. 255 256=head1 COMPATIBILITY WITH MIDL 257 258=head2 Missing features in pidl 259 260The following MIDL features are not (yet) implemented in pidl 261or are implemented with an incompatible interface: 262 263=over 264 265=item * 266 267Asynchronous communication 268 269=item * 270 271Typelibs (.tlb files) 272 273=item * 274 275Datagram support (ncadg_*) 276 277=back 278 279=head2 Supported attributes and statements 280 281in, out, ref, length_is, switch_is, size_is, uuid, case, default, string, 282unique, ptr, pointer_default, v1_enum, object, helpstring, range, local, 283call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as, 284transmit_as, import, include, cpp_quote. 285 286=head2 PIDL Specific properties 287 288=over 4 289 290=item public 291 292The [public] property on a structure or union is a pidl extension that 293forces the generated pull/push functions to be non-static. This allows 294you to declare types that can be used between modules. If you don't 295specify [public] then pull/push functions for other than top-level 296functions are declared static. 297 298=item noprint 299 300The [noprint] property is a pidl extension that allows you to specify 301that pidl should not generate a ndr_print_*() function for that 302structure or union. This is used when you wish to define your own 303print function that prints a structure in a nicer manner. A good 304example is the use of [noprint] on dom_sid, which allows the 305pretty-printing of SIDs. 306 307=item value 308 309The [value(expression)] property is a pidl extension that allows you 310to specify the value of a field when it is put on the wire. This 311allows fields that always have a well-known value to be automatically 312filled in, thus making the API more programmer friendly. The 313expression can be any C expression. 314 315=item relative 316 317The [relative] property can be supplied on a pointer. When it is used 318it declares the pointer as a spoolss style "relative" pointer, which 319means it appears on the wire as an offset within the current 320encapsulating structure. This is not part of normal IDL/NDR, but it is 321a very useful extension as it avoids the manual encoding of many 322complex structures. 323 324=item subcontext(length) 325 326Specifies that a size of I<length> 327bytes should be read, followed by a blob of that size, 328which will be parsed as NDR. 329 330subcontext() is deprecated now, and should not be used in new code. 331Instead, use represent_as() or transmit_as(). 332 333=item flag 334 335Specify boolean options, mostly used for 336low-level NDR options. Several options 337can be specified using the | character. 338Note that flags are inherited by substructures! 339 340=item nodiscriminant 341 342The [nodiscriminant] property on a union means that the usual uint16 343discriminent field at the start of the union on the wire is 344omitted. This is not normally allowed in IDL/NDR, but is used for some 345spoolss structures. 346 347=item charset(name) 348 349Specify that the array or string uses the specified 350charset. If this attribute is specified, pidl will 351take care of converting the character data from this format 352to the host format. Commonly used values are UCS2, DOS and UTF8. 353 354=back 355 356=head2 Unsupported MIDL properties or statements 357 358aggregatable, appobject, async_uuid, bindable, control, 359defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface, 360displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext, 361helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib, 362includelib, last_is, lcid, licensed, max_is, module, 363ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl, 364oleautomation, optional, pragma, propget, propputref, propput, readonly, 365requestedit, restricted, retval, source, uidefault, 366usesgetlasterror, vararg, vi_progid, wire_marshal. 367 368=head1 EXAMPLES 369 370 # Generating an Wireshark parser 371 $ ./pidl --ws-parser -- atsvc.idl 372 373 # Generating a TDR parser and header 374 $ ./pidl --tdr-parser --header -- regf.idl 375 376 # Generating a Samba3 client and server 377 $ ./pidl --samba3-ndr-client --samba3-ndr-server -- dfs.idl 378 379 # Generating a Samba4 NDR parser, client and server 380 $ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl 381 382=head1 SEE ALSO 383 384L<https://msdn.microsoft.com/en-us/library/windows/desktop/aa373864%28v=vs.85%29.aspx> 385L<https://gitlab.com/wireshark/wireshark/-/wikis/DCE/RPC>, 386L<https://www.samba.org/>, 387L<yapp(1)> 388 389=head1 LICENSE 390 391pidl is licensed under the GNU General Public License L<https://www.gnu.org/licenses/gpl.html>. 392 393=head1 AUTHOR 394 395pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer 396Vernooij. The current maintainer is Jelmer Vernooij. 397 398This manpage was written by Jelmer Vernooij, partially based on the original 399pidl README by Andrew Tridgell. 400 401=cut 402 403 404use strict; 405use FindBin qw($RealBin $Script); 406use lib "$RealBin/lib"; 407use Getopt::Long; 408use File::Basename; 409use Parse::Pidl qw ( $VERSION ); 410use Parse::Pidl::Util; 411use Parse::Pidl::ODL; 412 413##################################################################### 414# save a data structure into a file 415sub SaveStructure($$) 416{ 417 my($filename,$v) = @_; 418 FileSave($filename, Parse::Pidl::Util::MyDumper($v)); 419} 420 421##################################################################### 422# load a data structure from a file (as saved with SaveStructure) 423sub LoadStructure($) 424{ 425 my $f = shift; 426 my $contents = FileLoad($f); 427 defined $contents || return undef; 428 return eval "$contents"; 429} 430 431##################################################################### 432# read a file into a string 433sub FileLoad($) 434{ 435 my($filename) = shift; 436 local(*INPUTFILE); 437 open(INPUTFILE, $filename) || return undef; 438 my($saved_delim) = $/; 439 undef $/; 440 my($data) = <INPUTFILE>; 441 close(INPUTFILE); 442 $/ = $saved_delim; 443 return $data; 444} 445 446##################################################################### 447# write a string into a file 448sub FileSave($$) 449{ 450 my($filename) = shift; 451 my($v) = shift; 452 local(*FILE); 453 open(FILE, ">$filename") || die "can't open $filename"; 454 print FILE $v; 455 close(FILE); 456} 457 458my(@opt_incdirs) = (); 459my($opt_help) = 0; 460my($opt_version) = 0; 461my($opt_parse_idl_tree) = 0; 462my($opt_dump_idl_tree); 463my($opt_dump_ndr_tree); 464my($opt_dump_idl) = 0; 465my($opt_diff) = 0; 466my($opt_header); 467my($opt_samba3_header); 468my($opt_samba3_parser); 469my($opt_samba3_server); 470my($opt_samba3_ndr_client); 471my($opt_samba3_ndr_server); 472my($opt_samba3_template) = 0; 473my($opt_template) = 0; 474my($opt_client); 475my($opt_typelib); 476my($opt_server); 477my($opt_ndr_parser); 478my($opt_tdr_parser); 479my($opt_ws_parser); 480my($opt_python); 481my($opt_quiet) = 0; 482my($opt_outputdir) = '.'; 483my($opt_verbose) = 0; 484my($opt_warn_compat) = 0; 485my($opt_dcom_proxy); 486my($opt_com_header); 487 488######################################### 489# display help text 490sub ShowHelp() 491{ 492print "perl IDL parser and code generator\n"; 493ShowVersion(); 494print" 495Copyright (C) Andrew Tridgell <tridge\@samba.org> 496Copyright (C) Jelmer Vernooij <jelmer\@samba.org> 497 498Usage: $Script [options] [--] <idlfile> [<idlfile>...] 499 500Generic Options: 501 --help this help page 502 --version show pidl version 503 --outputdir=OUTDIR put output in OUTDIR/ [.] 504 --warn-compat warn about incompatibility with other compilers 505 --quiet be quiet 506 --verbose be verbose 507 --includedir DIR search DIR for included files 508 509Debugging: 510 --dump-idl-tree[=FILE] dump internal representation to file [BASENAME.pidl] 511 --parse-idl-tree read internal representation instead of IDL 512 --dump-ndr-tree[=FILE] dump internal NDR data tree to file [BASENAME.ndr] 513 --dump-idl regenerate IDL file 514 --diff run diff on original IDL and dumped output 515 --typelib print type information 516 517Samba 4 output: 518 --header[=OUTFILE] create generic header file [BASENAME.h] 519 --ndr-parser[=OUTFILE] create a C NDR parser [ndr_BASENAME.c] 520 --client[=OUTFILE] create a C NDR client [ndr_BASENAME_c.c] 521 --tdr-parser[=OUTFILE] create a C TDR parser [tdr_BASENAME.c] 522 --python[=OUTFILE] create python wrapper file [py_BASENAME.c] 523 --server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c] 524 --template print a template for a pipe 525 --dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c] 526 --com-header[=OUTFILE] create header for COM [com_BASENAME.h] 527 528Samba 3 output: 529 --samba3-ndr-client[=OUTF] create client calls for Samba3 530 using Samba4's NDR code [cli_BASENAME.c] 531 --samba3-ndr-server[=OUTF] create server call wrapper for Samba3 532 using Samba4's NDR code [srv_BASENAME.c] 533 --samba3-template print a template for a pipe 534 535Wireshark parsers: 536 --ws-parser[=OUTFILE] create Wireshark parser and header 537\n"; 538 exit(0); 539} 540 541######################################### 542# Display version 543sub ShowVersion() 544{ 545 print "perl IDL version $VERSION\n"; 546} 547 548# main program 549my $result = GetOptions ( 550 'help|h|?' => \$opt_help, 551 'version' => \$opt_version, 552 'outputdir=s' => \$opt_outputdir, 553 'dump-idl' => \$opt_dump_idl, 554 'dump-idl-tree:s' => \$opt_dump_idl_tree, 555 'parse-idl-tree' => \$opt_parse_idl_tree, 556 'dump-ndr-tree:s' => \$opt_dump_ndr_tree, 557 'samba3-ndr-client:s' => \$opt_samba3_ndr_client, 558 'samba3-ndr-server:s' => \$opt_samba3_ndr_server, 559 'samba3-template' => \$opt_samba3_template, 560 'header:s' => \$opt_header, 561 'server:s' => \$opt_server, 562 'typelib:s' => \$opt_typelib, 563 'tdr-parser:s' => \$opt_tdr_parser, 564 'template' => \$opt_template, 565 'ndr-parser:s' => \$opt_ndr_parser, 566 'client:s' => \$opt_client, 567 'ws-parser:s' => \$opt_ws_parser, 568 'python' => \$opt_python, 569 'diff' => \$opt_diff, 570 'dcom-proxy:s' => \$opt_dcom_proxy, 571 'com-header:s' => \$opt_com_header, 572 'quiet' => \$opt_quiet, 573 'verbose' => \$opt_verbose, 574 'warn-compat' => \$opt_warn_compat, 575 'includedir=s@' => \@opt_incdirs 576 ); 577 578if (not $result) { 579 exit(1); 580} 581 582if ($opt_help) { 583 ShowHelp(); 584 exit(0); 585} 586 587if ($opt_version) { 588 ShowVersion(); 589 exit(0); 590} 591 592sub process_file($) 593{ 594 my $idl_file = shift; 595 my $outputdir = $opt_outputdir; 596 my $pidl; 597 my $ndr; 598 599 my $basename = basename($idl_file, ".idl"); 600 601 unless ($opt_quiet) { print "Compiling $idl_file\n"; } 602 603 if ($opt_parse_idl_tree) { 604 $pidl = LoadStructure($idl_file); 605 defined $pidl || die "Failed to load $idl_file"; 606 } else { 607 require Parse::Pidl::IDL; 608 609 $pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs); 610 defined $pidl || die "Failed to parse $idl_file"; 611 } 612 613 require Parse::Pidl::Typelist; 614 Parse::Pidl::Typelist::LoadIdl($pidl, $basename); 615 616 if (defined($opt_dump_idl_tree)) { 617 my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl"); 618 SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n"; 619 } 620 621 if ($opt_dump_idl) { 622 require Parse::Pidl::Dump; 623 print Parse::Pidl::Dump($pidl); 624 } 625 626 if ($opt_diff) { 627 my($tempfile) = "$outputdir/$basename.tmp"; 628 FileSave($tempfile, IdlDump::Dump($pidl)); 629 system("diff -wu $idl_file $tempfile"); 630 unlink($tempfile); 631 } 632 633 my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h"); 634 if (defined($opt_com_header)) { 635 require Parse::Pidl::Samba4::COM::Header; 636 my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h"); 637 if ($res) { 638 FileSave($comh_filename, $res); 639 } 640 } 641 642 if (defined($opt_dcom_proxy)) { 643 require Parse::Pidl::Samba4::COM::Proxy; 644 my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename); 645 if ($res) { 646 my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c"); 647 FileSave($client, $res); 648 } 649 } 650 651 if ($opt_warn_compat) { 652 require Parse::Pidl::Compat; 653 Parse::Pidl::Compat::Check($pidl); 654 } 655 656 $pidl = Parse::Pidl::ODL::ODL2IDL($pidl, dirname($idl_file), \@opt_incdirs); 657 658 if (defined($opt_ws_parser)) { 659 require Parse::Pidl::Wireshark::NDR; 660 661 my $cnffile = $idl_file; 662 $cnffile =~ s/\.idl$/\.cnf/; 663 664 my $generator = new Parse::Pidl::Wireshark::NDR(); 665 $generator->Initialize($cnffile); 666 } 667 668 669 if (defined($opt_ws_parser) or 670 defined($opt_client) or 671 defined($opt_server) or 672 defined($opt_header) or 673 defined($opt_ndr_parser) or 674 defined($opt_python) or 675 defined($opt_dump_ndr_tree) or 676 defined($opt_samba3_header) or 677 defined($opt_samba3_parser) or 678 defined($opt_samba3_server) or 679 defined($opt_samba3_ndr_client) or 680 defined($opt_samba3_ndr_server)) { 681 require Parse::Pidl::NDR; 682 $ndr = Parse::Pidl::NDR::Parse($pidl); 683 } 684 685 if (defined($opt_dump_ndr_tree)) { 686 my($ndr_file) = ($opt_dump_ndr_tree or "$outputdir/$basename.ndr"); 687 SaveStructure($ndr_file, $ndr) or die "Failed to save $ndr_file\n"; 688 } 689 690 my $gen_header = ($opt_header or "$outputdir/$basename.h"); 691 if (defined($opt_header)) { 692 require Parse::Pidl::Samba4::Header; 693 FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($ndr)); 694 } 695 696 my $h_filename = "$outputdir/ndr_$basename.h"; 697 my $c_header = "$outputdir/ndr_$basename\_c.h"; 698 if (defined($opt_client) or defined($opt_samba3_ndr_client)) { 699 require Parse::Pidl::Samba4::NDR::Client; 700 my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c"); 701 $c_header = $c_client; 702 $c_header =~ s/\.c$/.h/; 703 704 my $generator = new Parse::Pidl::Samba4::NDR::Client(); 705 my ($srcd,$hdrd) = $generator->Parse( 706 $ndr,$gen_header,$h_filename,$c_header); 707 708 FileSave($c_client, $srcd); 709 FileSave($c_header, $hdrd); 710 } 711 712 if (defined($opt_python)) { 713 require Parse::Pidl::Samba4::Python; 714 my $generator = new Parse::Pidl::Samba4::Python(); 715 my ($prsr) = $generator->Parse($basename, $ndr, 716 "$outputdir/ndr_$basename\_c.h", $h_filename); 717 FileSave("$outputdir/py_$basename.c", $prsr); 718 } 719 720 if (defined($opt_server)) { 721 require Parse::Pidl::Samba4::NDR::Server; 722 723 FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename)); 724 } 725 726 if (defined($opt_ndr_parser)) { 727 my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c"); 728 require Parse::Pidl::Samba4::NDR::Parser; 729 my $generator = new Parse::Pidl::Samba4::NDR::Parser(); 730 my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename); 731 732 FileSave($parser_fname, $parser); 733 FileSave($h_filename, $header); 734 735 } 736 737 if (defined($opt_ws_parser)) { 738 require Parse::Pidl::Wireshark::NDR; 739 my($eparser) = ($opt_ws_parser or "$outputdir/packet-dcerpc-$basename.c"); 740 my $eheader = $eparser; 741 $eheader =~ s/\.c$/\.h/; 742 my $cnffile = $idl_file; 743 $cnffile =~ s/\.idl$/\.cnf/; 744 745 my $generator = new Parse::Pidl::Wireshark::NDR(); 746 my ($dp, $dh) = $generator->Parse($ndr, $idl_file, $eheader, $cnffile); 747 FileSave($eparser, $dp) if defined($dp); 748 FileSave($eheader, $dh) if defined($dh); 749 } 750 751 if (defined($opt_tdr_parser)) { 752 my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c"); 753 my $tdr_header = $tdr_parser; 754 $tdr_header =~ s/\.c$/\.h/; 755 require Parse::Pidl::Samba4::TDR; 756 my $generator = new Parse::Pidl::Samba4::TDR(); 757 my ($hdr,$prsr) = $generator->Parser($pidl, $tdr_header, $gen_header); 758 FileSave($tdr_parser, $prsr); 759 FileSave($tdr_header, $hdr); 760 } 761 762 if (defined($opt_typelib)) { 763 my $typelib = ($opt_typelib or "$outputdir/$basename.tlb"); 764 require Parse::Pidl::Typelist; 765 FileSave($typelib, Parse::Pidl::Typelist::GenerateTypeLib()); 766 } 767 768 if ($opt_template) { 769 require Parse::Pidl::Samba4::Template; 770 print Parse::Pidl::Samba4::Template::Parse($pidl); 771 } 772 773 if ($opt_samba3_template) { 774 require Parse::Pidl::Samba3::Template; 775 print Parse::Pidl::Samba3::Template::Parse($pidl); 776 } 777 778 if (defined($opt_samba3_ndr_client)) { 779 my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c"); 780 my $header = $client; $header =~ s/\.c$/\.h/; 781 require Parse::Pidl::Samba3::ClientNDR; 782 my $generator = new Parse::Pidl::Samba3::ClientNDR(); 783 my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header); 784 FileSave($client, $c_code); 785 FileSave($header, $h_code); 786 } 787 788 if (defined($opt_samba3_ndr_server)) { 789 my $server = ($opt_samba3_ndr_server or "$outputdir/srv_$basename.c"); 790 my $header = $server; $header =~ s/\.c$/\.h/; 791 require Parse::Pidl::Samba3::ServerNDR; 792 my ($c_code,$h_code) = Parse::Pidl::Samba3::ServerNDR::Parse($ndr, $header, $h_filename); 793 FileSave($server, $c_code); 794 FileSave($header, $h_code); 795 } 796 797} 798 799if (scalar(@ARGV) == 0) { 800 print "$Script: no input files\n"; 801 exit(1); 802} 803 804process_file($_) foreach (@ARGV); 805