840 lines
24 KiB
Perl
Executable File
840 lines
24 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
|
|
###################################################
|
|
# package to parse IDL files and generate code for
|
|
# rpc functions in Samba
|
|
# Copyright tridge@samba.org 2000-2003
|
|
# Copyright jelmer@samba.org 2005-2007
|
|
# released under the GNU GPL
|
|
# Modifications for COMROGUE - Copyright erbo@erbosoft.com 2013
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
pidl - An IDL compiler written in Perl
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
pidl --help
|
|
|
|
pidl [--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]] [--comrogue-header=[OUTPUT]] [<idlfile>.idl]...
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
pidl is an IDL compiler written in Perl that aims to be somewhat
|
|
compatible with the midl compiler. IDL is short for
|
|
"Interface Definition Language".
|
|
|
|
pidl can generate stubs for DCE/RPC server code, DCE/RPC
|
|
client code and Wireshark dissectors for DCE/RPC traffic.
|
|
|
|
IDL compilers like pidl take a description
|
|
of an interface as their input and use it to generate C
|
|
(though support for other languages may be added later) code that
|
|
can use these interfaces, pretty print data sent
|
|
using these interfaces, or even generate Wireshark
|
|
dissectors that can parse data sent over the
|
|
wire by these interfaces.
|
|
|
|
pidl takes IDL files in the same format as is used by midl,
|
|
converts it to a .pidl file (which contains pidl's internal representation of the interface) and can then generate whatever output you need.
|
|
.pidl files should be used for debugging purposes only. Write your
|
|
interface definitions in .idl format.
|
|
|
|
The goal of pidl is to implement a IDL compiler that can be used
|
|
while developing the RPC subsystem in Samba (for
|
|
both marshalling/unmarshalling and debugging purposes).
|
|
|
|
For COMROGUE, pidl generates the header files for interfaces.
|
|
|
|
=head1 OPTIONS
|
|
|
|
=over 4
|
|
|
|
=item I<--help>
|
|
|
|
Show list of available options.
|
|
|
|
=item I<--version>
|
|
|
|
Show pidl version
|
|
|
|
=item I<--outputdir OUTNAME>
|
|
|
|
Write output files to the specified directory. Defaults to the current
|
|
directory.
|
|
|
|
=item I<--includedir DIR>
|
|
|
|
Add DIR to the search path used by the preprocessor. This option can be
|
|
specified multiple times.
|
|
|
|
=item I<--parse-idl-tree>
|
|
|
|
Read internal tree structure from input files rather
|
|
than assuming they contain IDL.
|
|
|
|
=item I<--dump-idl>
|
|
|
|
Generate a new IDL file. File will be named OUTNAME.idl.
|
|
|
|
=item I<--header>
|
|
|
|
Generate a C header file for the specified interface. Filename defaults to OUTNAME.h.
|
|
|
|
=item I<--ndr-parser>
|
|
|
|
Generate a C file and C header containing NDR parsers. The filename for
|
|
the parser defaults to ndr_OUTNAME.c. The header filename will be the
|
|
parser filename with the extension changed from .c to .h.
|
|
|
|
=item I<--tdr-parser>
|
|
|
|
Generate a C file and C header containing TDR parsers. The filename for
|
|
the parser defaults to tdr_OUTNAME.c. The header filename will be the
|
|
parser filename with the extension changed from .c to .h.
|
|
|
|
=item I<--typelib>
|
|
|
|
Write type information to the specified file.
|
|
|
|
=item I<--server>
|
|
|
|
Generate boilerplate for the RPC server that implements
|
|
the interface. Filename defaults to ndr_OUTNAME_s.c.
|
|
|
|
=item I<--template>
|
|
|
|
Generate stubs for a RPC server that implements the interface. Output will
|
|
be written to stdout.
|
|
|
|
=item I<--ws-parser>
|
|
|
|
Generate an Wireshark dissector (in C) and header file. The dissector filename
|
|
defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to
|
|
packet-dcerpc-OUTNAME.h.
|
|
|
|
Pidl will read additional data from an Wireshark conformance file if present.
|
|
Such a file should have the same location as the IDL file but with the
|
|
extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance>
|
|
for details on the format of this file.
|
|
|
|
=item I<--diff>
|
|
|
|
Parse an IDL file, generate a new IDL file based on the internal data
|
|
structures and see if there are any differences with the original IDL file.
|
|
Useful for debugging pidl.
|
|
|
|
=item I<--dump-idl-tree>
|
|
|
|
Tell pidl to dump the internal tree representation of an IDL
|
|
file the to disk. Useful for debugging pidl.
|
|
|
|
=item I<--dump-ndr-tree>
|
|
|
|
Tell pidl to dump the internal NDR information tree it generated
|
|
from the IDL file to disk. Useful for debugging pidl.
|
|
|
|
=item I<--samba3-ndr-client>
|
|
|
|
Generate client calls for Samba3, to be placed in rpc_client/. Instead of
|
|
calling out to the code in Samba3's rpc_parse/, this will call out to
|
|
Samba4's NDR code instead.
|
|
|
|
=item I<--samba3-ndr-server>
|
|
|
|
Generate server calls for Samba3, to be placed in rpc_server/. Instead of
|
|
calling out to the code in Samba3's rpc_parse/, this will call out to
|
|
Samba4's NDR code instead.
|
|
|
|
=item I<--comrogue-header>
|
|
|
|
Generate interface header files for COMROGUE. Filename defaults to
|
|
OUTNAME.h.
|
|
|
|
=back
|
|
|
|
=head1 IDL SYNTAX
|
|
|
|
IDL files are always preprocessed using the C preprocessor.
|
|
|
|
Pretty much everything in an interface (the interface itself, functions,
|
|
parameters) can have attributes (or properties whatever name you give them).
|
|
Attributes always prepend the element they apply to and are surrounded
|
|
by square brackets ([]). Multiple attributes are separated by comma's;
|
|
arguments to attributes are specified between parentheses.
|
|
|
|
See the section COMPATIBILITY for the list of attributes that
|
|
pidl supports.
|
|
|
|
C-style comments can be used.
|
|
|
|
=head2 CONFORMANT ARRAYS
|
|
|
|
A conformant array is one with that ends in [*] or []. The strange
|
|
things about conformant arrays are that they can only appear as the last
|
|
element of a structure (unless there is a pointer to the conformant array,
|
|
of course) and the array size appears before the structure itself on the wire.
|
|
|
|
So, in this example:
|
|
|
|
typedef struct {
|
|
long abc;
|
|
long count;
|
|
long foo;
|
|
[size_is(count)] long s[*];
|
|
} Struct1;
|
|
|
|
it appears like this:
|
|
|
|
[size_is] [abc] [count] [foo] [s...]
|
|
|
|
the first [size_is] field is the allocation size of the array, and
|
|
occurs before the array elements and even before the structure
|
|
alignment.
|
|
|
|
Note that size_is() can refer to a constant, but that doesn't change
|
|
the wire representation. It does not make the array a fixed array.
|
|
|
|
midl.exe would write the above array as the following C header:
|
|
|
|
typedef struct {
|
|
long abc;
|
|
long count;
|
|
long foo;
|
|
long s[1];
|
|
} Struct1;
|
|
|
|
pidl takes a different approach, and writes it like this:
|
|
|
|
typedef struct {
|
|
long abc;
|
|
long count;
|
|
long foo;
|
|
long *s;
|
|
} Struct1;
|
|
|
|
=head2 VARYING ARRAYS
|
|
|
|
A varying array looks like this:
|
|
|
|
typedef struct {
|
|
long abc;
|
|
long count;
|
|
long foo;
|
|
[size_is(count)] long *s;
|
|
} Struct1;
|
|
|
|
This will look like this on the wire:
|
|
|
|
[abc] [count] [foo] [PTR_s] [count] [s...]
|
|
|
|
=head2 FIXED ARRAYS
|
|
|
|
A fixed array looks like this:
|
|
|
|
typedef struct {
|
|
long s[10];
|
|
} Struct1;
|
|
|
|
The NDR representation looks just like 10 separate long
|
|
declarations. The array size is not encoded on the wire.
|
|
|
|
pidl also supports "inline" arrays, which are not part of the IDL/NDR
|
|
standard. These are declared like this:
|
|
|
|
typedef struct {
|
|
uint32 foo;
|
|
uint32 count;
|
|
uint32 bar;
|
|
long s[count];
|
|
} Struct1;
|
|
|
|
This appears like this:
|
|
|
|
[foo] [count] [bar] [s...]
|
|
|
|
Fixed arrays are an extension added to support some of the strange
|
|
embedded structures in security descriptors and spoolss.
|
|
|
|
This section is by no means complete. See the OpenGroup and MSDN
|
|
documentation for additional information.
|
|
|
|
=head1 COMPATIBILITY WITH MIDL
|
|
|
|
=head2 Missing features in pidl
|
|
|
|
The following MIDL features are not (yet) implemented in pidl
|
|
or are implemented with an incompatible interface:
|
|
|
|
=over
|
|
|
|
=item *
|
|
|
|
Asynchronous communication
|
|
|
|
=item *
|
|
|
|
Typelibs (.tlb files)
|
|
|
|
=item *
|
|
|
|
Datagram support (ncadg_*)
|
|
|
|
=back
|
|
|
|
=head2 Supported attributes and statements
|
|
|
|
in, out, ref, length_is, switch_is, size_is, uuid, case, default, string,
|
|
unique, ptr, pointer_default, v1_enum, object, helpstring, range, local,
|
|
call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as,
|
|
transmit_as, import, include, cpp_quote.
|
|
|
|
=head2 PIDL Specific properties
|
|
|
|
=over 4
|
|
|
|
=item public
|
|
|
|
The [public] property on a structure or union is a pidl extension that
|
|
forces the generated pull/push functions to be non-static. This allows
|
|
you to declare types that can be used between modules. If you don't
|
|
specify [public] then pull/push functions for other than top-level
|
|
functions are declared static.
|
|
|
|
=item noprint
|
|
|
|
The [noprint] property is a pidl extension that allows you to specify
|
|
that pidl should not generate a ndr_print_*() function for that
|
|
structure or union. This is used when you wish to define your own
|
|
print function that prints a structure in a nicer manner. A good
|
|
example is the use of [noprint] on dom_sid, which allows the
|
|
pretty-printing of SIDs.
|
|
|
|
=item value
|
|
|
|
The [value(expression)] property is a pidl extension that allows you
|
|
to specify the value of a field when it is put on the wire. This
|
|
allows fields that always have a well-known value to be automatically
|
|
filled in, thus making the API more programmer friendly. The
|
|
expression can be any C expression.
|
|
|
|
=item relative
|
|
|
|
The [relative] property can be supplied on a pointer. When it is used
|
|
it declares the pointer as a spoolss style "relative" pointer, which
|
|
means it appears on the wire as an offset within the current
|
|
encapsulating structure. This is not part of normal IDL/NDR, but it is
|
|
a very useful extension as it avoids the manual encoding of many
|
|
complex structures.
|
|
|
|
=item subcontext(length)
|
|
|
|
Specifies that a size of I<length>
|
|
bytes should be read, followed by a blob of that size,
|
|
which will be parsed as NDR.
|
|
|
|
subcontext() is deprecated now, and should not be used in new code.
|
|
Instead, use represent_as() or transmit_as().
|
|
|
|
=item flag
|
|
|
|
Specify boolean options, mostly used for
|
|
low-level NDR options. Several options
|
|
can be specified using the | character.
|
|
Note that flags are inherited by substructures!
|
|
|
|
=item nodiscriminant
|
|
|
|
The [nodiscriminant] property on a union means that the usual uint16
|
|
discriminent field at the start of the union on the wire is
|
|
omitted. This is not normally allowed in IDL/NDR, but is used for some
|
|
spoolss structures.
|
|
|
|
=item charset(name)
|
|
|
|
Specify that the array or string uses the specified
|
|
charset. If this attribute is specified, pidl will
|
|
take care of converting the character data from this format
|
|
to the host format. Commonly used values are UCS2, DOS and UTF8.
|
|
|
|
=back
|
|
|
|
=head2 Unsupported MIDL properties or statements
|
|
|
|
aggregatable, appobject, async_uuid, bindable, control,
|
|
defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface,
|
|
displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext,
|
|
helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib,
|
|
includelib, last_is, lcid, licensed, max_is, module,
|
|
ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl,
|
|
oleautomation, optional, pragma, propget, propputref, propput, readonly,
|
|
requestedit, restricted, retval, source, uidefault,
|
|
usesgetlasterror, vararg, vi_progid, wire_marshal.
|
|
|
|
=head1 EXAMPLES
|
|
|
|
# Generating an Wireshark parser
|
|
$ ./pidl --ws-parser -- atsvc.idl
|
|
|
|
# Generating a TDR parser and header
|
|
$ ./pidl --tdr-parser --header -- regf.idl
|
|
|
|
# Generating a Samba3 client and server
|
|
$ ./pidl --samba3-ndr-client --samba3-ndr-server -- dfs.idl
|
|
|
|
# Generating a Samba4 NDR parser, client and server
|
|
$ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>,
|
|
L<http://wiki.wireshark.org/DCE/RPC>,
|
|
L<http://www.samba.org/>,
|
|
L<yapp(1)>
|
|
|
|
=head1 LICENSE
|
|
|
|
pidl is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
|
|
|
|
=head1 AUTHOR
|
|
|
|
pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer
|
|
Vernooij. The current maintainer is Jelmer Vernooij.
|
|
|
|
This manpage was written by Jelmer Vernooij, partially based on the original
|
|
pidl README by Andrew Tridgell.
|
|
|
|
This code has been modified for use with the COMROGUE operating system by Eric J. Bowersox.
|
|
|
|
=cut
|
|
|
|
|
|
use strict;
|
|
use FindBin qw($RealBin $Script);
|
|
use lib "$RealBin/lib";
|
|
use lib "$RealBin/../share/perl5";
|
|
use Getopt::Long;
|
|
use File::Basename;
|
|
use Parse::Pidl qw ( $VERSION );
|
|
use Parse::Pidl::Util;
|
|
use Parse::Pidl::ODL;
|
|
|
|
#####################################################################
|
|
# save a data structure into a file
|
|
sub SaveStructure($$)
|
|
{
|
|
my($filename,$v) = @_;
|
|
FileSave($filename, Parse::Pidl::Util::MyDumper($v));
|
|
}
|
|
|
|
#####################################################################
|
|
# load a data structure from a file (as saved with SaveStructure)
|
|
sub LoadStructure($)
|
|
{
|
|
my $f = shift;
|
|
my $contents = FileLoad($f);
|
|
defined $contents || return undef;
|
|
return eval "$contents";
|
|
}
|
|
|
|
#####################################################################
|
|
# read a file into a string
|
|
sub FileLoad($)
|
|
{
|
|
my($filename) = shift;
|
|
local(*INPUTFILE);
|
|
open(INPUTFILE, $filename) || return undef;
|
|
my($saved_delim) = $/;
|
|
undef $/;
|
|
my($data) = <INPUTFILE>;
|
|
close(INPUTFILE);
|
|
$/ = $saved_delim;
|
|
return $data;
|
|
}
|
|
|
|
#####################################################################
|
|
# write a string into a file
|
|
sub FileSave($$)
|
|
{
|
|
my($filename) = shift;
|
|
my($v) = shift;
|
|
local(*FILE);
|
|
open(FILE, ">$filename") || die "can't open $filename";
|
|
print FILE $v;
|
|
close(FILE);
|
|
}
|
|
|
|
my(@opt_incdirs) = ();
|
|
my($opt_help) = 0;
|
|
my($opt_version) = 0;
|
|
my($opt_parse_idl_tree) = 0;
|
|
my($opt_dump_idl_tree);
|
|
my($opt_dump_ndr_tree);
|
|
my($opt_dump_idl) = 0;
|
|
my($opt_diff) = 0;
|
|
my($opt_header);
|
|
my($opt_samba3_header);
|
|
my($opt_samba3_parser);
|
|
my($opt_samba3_server);
|
|
my($opt_samba3_ndr_client);
|
|
my($opt_samba3_ndr_server);
|
|
my($opt_template) = 0;
|
|
my($opt_client);
|
|
my($opt_typelib);
|
|
my($opt_server);
|
|
my($opt_ndr_parser);
|
|
my($opt_tdr_parser);
|
|
my($opt_ws_parser);
|
|
my($opt_python);
|
|
my($opt_quiet) = 0;
|
|
my($opt_outputdir) = '.';
|
|
my($opt_verbose) = 0;
|
|
my($opt_warn_compat) = 0;
|
|
my($opt_dcom_proxy);
|
|
my($opt_com_header);
|
|
my($opt_comrogue_header);
|
|
|
|
#########################################
|
|
# display help text
|
|
sub ShowHelp()
|
|
{
|
|
print "perl IDL parser and code generator\n";
|
|
ShowVersion();
|
|
print"
|
|
Copyright (C) Andrew Tridgell <tridge\@samba.org>
|
|
Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
|
|
|
|
Usage: $Script [options] [--] <idlfile> [<idlfile>...]
|
|
|
|
Generic Options:
|
|
--help this help page
|
|
--version show pidl version
|
|
--outputdir=OUTDIR put output in OUTDIR/ [.]
|
|
--warn-compat warn about incompatibility with other compilers
|
|
--quiet be quiet
|
|
--verbose be verbose
|
|
--includedir DIR search DIR for included files
|
|
|
|
Debugging:
|
|
--dump-idl-tree[=FILE] dump internal representation to file [BASENAME.pidl]
|
|
--parse-idl-tree read internal representation instead of IDL
|
|
--dump-ndr-tree[=FILE] dump internal NDR data tree to file [BASENAME.ndr]
|
|
--dump-idl regenerate IDL file
|
|
--diff run diff on original IDL and dumped output
|
|
--typelib print type information
|
|
|
|
Samba 4 output:
|
|
--header[=OUTFILE] create generic header file [BASENAME.h]
|
|
--ndr-parser[=OUTFILE] create a C NDR parser [ndr_BASENAME.c]
|
|
--client[=OUTFILE] create a C NDR client [ndr_BASENAME_c.c]
|
|
--tdr-parser[=OUTFILE] create a C TDR parser [tdr_BASENAME.c]
|
|
--python[=OUTFILE] create python wrapper file [py_BASENAME.c]
|
|
--server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c]
|
|
--template print a template for a pipe
|
|
--dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c]
|
|
--com-header[=OUTFILE] create header for COM [com_BASENAME.h]
|
|
|
|
Samba 3 output:
|
|
--samba3-ndr-client[=OUTF] create client calls for Samba3
|
|
using Samba4's NDR code [cli_BASENAME.c]
|
|
--samba3-ndr-server[=OUTF] create server call wrapper for Samba3
|
|
using Samba4's NDR code [srv_BASENAME.c]
|
|
|
|
Wireshark parsers:
|
|
--ws-parser[=OUTFILE] create Wireshark parser and header
|
|
|
|
COMROGUE:
|
|
--comrogue-header[=OUTFILE] create header for COMROGUE interface
|
|
[BASENAME.h]
|
|
\n";
|
|
exit(0);
|
|
}
|
|
|
|
#########################################
|
|
# Display version
|
|
sub ShowVersion()
|
|
{
|
|
print "perl IDL version $VERSION\n";
|
|
}
|
|
|
|
# main program
|
|
my $result = GetOptions (
|
|
'help|h|?' => \$opt_help,
|
|
'version' => \$opt_version,
|
|
'outputdir=s' => \$opt_outputdir,
|
|
'dump-idl' => \$opt_dump_idl,
|
|
'dump-idl-tree:s' => \$opt_dump_idl_tree,
|
|
'parse-idl-tree' => \$opt_parse_idl_tree,
|
|
'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
|
|
'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
|
|
'samba3-ndr-server:s' => \$opt_samba3_ndr_server,
|
|
'header:s' => \$opt_header,
|
|
'server:s' => \$opt_server,
|
|
'typelib:s' => \$opt_typelib,
|
|
'tdr-parser:s' => \$opt_tdr_parser,
|
|
'template' => \$opt_template,
|
|
'ndr-parser:s' => \$opt_ndr_parser,
|
|
'client:s' => \$opt_client,
|
|
'ws-parser:s' => \$opt_ws_parser,
|
|
'python' => \$opt_python,
|
|
'diff' => \$opt_diff,
|
|
'dcom-proxy:s' => \$opt_dcom_proxy,
|
|
'com-header:s' => \$opt_com_header,
|
|
'comrogue-header:s' => \$opt_comrogue_header,
|
|
'quiet' => \$opt_quiet,
|
|
'verbose' => \$opt_verbose,
|
|
'warn-compat' => \$opt_warn_compat,
|
|
'includedir=s@' => \@opt_incdirs
|
|
);
|
|
|
|
if (not $result) {
|
|
exit(1);
|
|
}
|
|
|
|
if ($opt_help) {
|
|
ShowHelp();
|
|
exit(0);
|
|
}
|
|
|
|
if ($opt_version) {
|
|
ShowVersion();
|
|
exit(0);
|
|
}
|
|
|
|
sub process_imports($)
|
|
{
|
|
my $pidl = shift;
|
|
foreach my $d (@{$pidl})
|
|
{
|
|
next unless $d->{TYPE} eq "IMPORT";
|
|
foreach my $p (@{$d->{PATHS}}) {
|
|
my $f = Parse::Pidl::IDL::parse_file($p, \@opt_incdirs);
|
|
defined @$f || die "Failed to parse $p";
|
|
my $basename = basename($p, ".idl");
|
|
Parse::Pidl::Typelist::LoadIdl($f, $basename);
|
|
process_imports($f);
|
|
}
|
|
}
|
|
}
|
|
|
|
sub process_file($)
|
|
{
|
|
my $idl_file = shift;
|
|
my $outputdir = $opt_outputdir;
|
|
my $pidl;
|
|
my $ndr;
|
|
|
|
my $basename = basename($idl_file, ".idl");
|
|
|
|
unless ($opt_quiet) { print "Compiling $idl_file\n"; }
|
|
|
|
if ($opt_parse_idl_tree) {
|
|
$pidl = LoadStructure($idl_file);
|
|
defined $pidl || die "Failed to load $idl_file";
|
|
} else {
|
|
require Parse::Pidl::IDL;
|
|
|
|
$pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs);
|
|
defined @$pidl || die "Failed to parse $idl_file";
|
|
}
|
|
|
|
require Parse::Pidl::Typelist;
|
|
Parse::Pidl::Typelist::LoadIdl($pidl, $basename);
|
|
|
|
if (defined($opt_dump_idl_tree)) {
|
|
my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl");
|
|
SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n";
|
|
}
|
|
|
|
if ($opt_dump_idl) {
|
|
require Parse::Pidl::Dump;
|
|
print Parse::Pidl::Dump($pidl);
|
|
}
|
|
|
|
if ($opt_diff) {
|
|
my($tempfile) = "$outputdir/$basename.tmp";
|
|
FileSave($tempfile, IdlDump::Dump($pidl));
|
|
system("diff -wu $idl_file $tempfile");
|
|
unlink($tempfile);
|
|
}
|
|
|
|
my $crh_filename = ($opt_comrogue_header or "$outputdir/$basename.h");
|
|
if (defined($opt_comrogue_header)) {
|
|
process_imports($pidl);
|
|
require Parse::Pidl::COMROGUE::Header;
|
|
my $res = Parse::Pidl::COMROGUE::Header::Parse($pidl,$basename,$idl_file);
|
|
if ($res) {
|
|
FileSave($crh_filename, $res);
|
|
}
|
|
}
|
|
|
|
my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h");
|
|
if (defined($opt_com_header)) {
|
|
require Parse::Pidl::Samba4::COM::Header;
|
|
my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h");
|
|
if ($res) {
|
|
FileSave($comh_filename, $res);
|
|
}
|
|
}
|
|
|
|
if (defined($opt_dcom_proxy)) {
|
|
require Parse::Pidl::Samba4::COM::Proxy;
|
|
my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename);
|
|
if ($res) {
|
|
my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c");
|
|
FileSave($client, $res);
|
|
}
|
|
}
|
|
|
|
if ($opt_warn_compat) {
|
|
require Parse::Pidl::Compat;
|
|
Parse::Pidl::Compat::Check($pidl);
|
|
}
|
|
|
|
$pidl = Parse::Pidl::ODL::ODL2IDL($pidl, dirname($idl_file), \@opt_incdirs);
|
|
|
|
if (defined($opt_ws_parser)) {
|
|
require Parse::Pidl::Wireshark::NDR;
|
|
|
|
my $cnffile = $idl_file;
|
|
$cnffile =~ s/\.idl$/\.cnf/;
|
|
|
|
my $generator = new Parse::Pidl::Wireshark::NDR();
|
|
$generator->Initialize($cnffile);
|
|
}
|
|
|
|
|
|
if (defined($opt_ws_parser) or
|
|
defined($opt_client) or
|
|
defined($opt_server) or
|
|
defined($opt_header) or
|
|
defined($opt_ndr_parser) or
|
|
defined($opt_python) or
|
|
defined($opt_dump_ndr_tree) or
|
|
defined($opt_samba3_header) or
|
|
defined($opt_samba3_parser) or
|
|
defined($opt_samba3_server) or
|
|
defined($opt_samba3_ndr_client) or
|
|
defined($opt_samba3_ndr_server)) {
|
|
require Parse::Pidl::NDR;
|
|
$ndr = Parse::Pidl::NDR::Parse($pidl);
|
|
}
|
|
|
|
if (defined($opt_dump_ndr_tree)) {
|
|
my($ndr_file) = ($opt_dump_ndr_tree or "$outputdir/$basename.ndr");
|
|
SaveStructure($ndr_file, $ndr) or die "Failed to save $ndr_file\n";
|
|
}
|
|
|
|
my $gen_header = ($opt_header or "$outputdir/$basename.h");
|
|
if (defined($opt_header)) {
|
|
require Parse::Pidl::Samba4::Header;
|
|
FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($ndr));
|
|
}
|
|
|
|
my $h_filename = "$outputdir/ndr_$basename.h";
|
|
my $c_header = "$outputdir/ndr_$basename\_c.h";
|
|
if (defined($opt_client) or defined($opt_samba3_ndr_client)) {
|
|
require Parse::Pidl::Samba4::NDR::Client;
|
|
my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
|
|
$c_header = $c_client;
|
|
$c_header =~ s/\.c$/.h/;
|
|
|
|
my $generator = new Parse::Pidl::Samba4::NDR::Client();
|
|
my ($srcd,$hdrd) = $generator->Parse(
|
|
$ndr,$gen_header,$h_filename,$c_header);
|
|
|
|
FileSave($c_client, $srcd);
|
|
FileSave($c_header, $hdrd);
|
|
}
|
|
|
|
if (defined($opt_python)) {
|
|
require Parse::Pidl::Samba4::Python;
|
|
my $generator = new Parse::Pidl::Samba4::Python();
|
|
my ($prsr) = $generator->Parse($basename, $ndr,
|
|
"$outputdir/ndr_$basename\_c.h", $h_filename);
|
|
FileSave("$outputdir/py_$basename.c", $prsr);
|
|
}
|
|
|
|
if (defined($opt_server)) {
|
|
require Parse::Pidl::Samba4::NDR::Server;
|
|
|
|
FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename));
|
|
}
|
|
|
|
if (defined($opt_ndr_parser)) {
|
|
my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c");
|
|
require Parse::Pidl::Samba4::NDR::Parser;
|
|
my $generator = new Parse::Pidl::Samba4::NDR::Parser();
|
|
my ($header,$parser) = $generator->Parse($ndr, $gen_header, $h_filename);
|
|
|
|
FileSave($parser_fname, $parser);
|
|
FileSave($h_filename, $header);
|
|
|
|
}
|
|
|
|
if (defined($opt_ws_parser)) {
|
|
require Parse::Pidl::Wireshark::NDR;
|
|
my($eparser) = ($opt_ws_parser or "$outputdir/packet-dcerpc-$basename.c");
|
|
my $eheader = $eparser;
|
|
$eheader =~ s/\.c$/\.h/;
|
|
my $cnffile = $idl_file;
|
|
$cnffile =~ s/\.idl$/\.cnf/;
|
|
|
|
my $generator = new Parse::Pidl::Wireshark::NDR();
|
|
my ($dp, $dh) = $generator->Parse($ndr, $idl_file, $eheader, $cnffile);
|
|
FileSave($eparser, $dp) if defined($dp);
|
|
FileSave($eheader, $dh) if defined($dh);
|
|
}
|
|
|
|
if (defined($opt_tdr_parser)) {
|
|
my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c");
|
|
my $tdr_header = $tdr_parser;
|
|
$tdr_header =~ s/\.c$/\.h/;
|
|
require Parse::Pidl::Samba4::TDR;
|
|
my $generator = new Parse::Pidl::Samba4::TDR();
|
|
my ($hdr,$prsr) = $generator->Parser($pidl, $tdr_header, $gen_header);
|
|
FileSave($tdr_parser, $prsr);
|
|
FileSave($tdr_header, $hdr);
|
|
}
|
|
|
|
if (defined($opt_typelib)) {
|
|
my $typelib = ($opt_typelib or "$outputdir/$basename.tlb");
|
|
require Parse::Pidl::Typelist;
|
|
FileSave($typelib, Parse::Pidl::Typelist::GenerateTypeLib());
|
|
}
|
|
|
|
if ($opt_template) {
|
|
require Parse::Pidl::Samba4::Template;
|
|
print Parse::Pidl::Samba4::Template::Parse($pidl);
|
|
}
|
|
|
|
if (defined($opt_samba3_ndr_client)) {
|
|
my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
|
|
my $header = $client; $header =~ s/\.c$/\.h/;
|
|
require Parse::Pidl::Samba3::ClientNDR;
|
|
my $generator = new Parse::Pidl::Samba3::ClientNDR();
|
|
my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header);
|
|
FileSave($client, $c_code);
|
|
FileSave($header, $h_code);
|
|
}
|
|
|
|
if (defined($opt_samba3_ndr_server)) {
|
|
my $server = ($opt_samba3_ndr_server or "$outputdir/srv_$basename.c");
|
|
my $header = $server; $header =~ s/\.c$/\.h/;
|
|
require Parse::Pidl::Samba3::ServerNDR;
|
|
my ($c_code,$h_code) = Parse::Pidl::Samba3::ServerNDR::Parse($ndr, $header, $h_filename);
|
|
FileSave($server, $c_code);
|
|
FileSave($header, $h_code);
|
|
}
|
|
|
|
}
|
|
|
|
if (scalar(@ARGV) == 0) {
|
|
print "$Script: no input files\n";
|
|
exit(1);
|
|
}
|
|
|
|
process_file($_) foreach (@ARGV);
|