Machine Interface Utility:VER1.0

This commit is contained in:
TAO Cheng
2013-05-09 20:29:54 +08:00
commit 036cdcb228
743 changed files with 104786 additions and 0 deletions
@@ -0,0 +1,8 @@
copyright (c) 2010 Pete Batard <pbatard@gmail.com>
copyright (c) 2010 Travis Robinson <libusbdotnet@gmail.com>
zadic improvements:
copyright (c) 2010 Joseph Marshall <jmarshall@gcdataconcepts.com>
libconfig authors:
Mark Lindner, Daniel Marjamäki, Andrew Tytula, Glenn Herteg
@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
@@ -0,0 +1 @@
1.0.0 ALPHA
@@ -0,0 +1,27 @@
AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip
ACLOCAL_AMFLAGS = -I m4
#DISTCLEANFILES = ChangeLog libusb-1.0.pc
#EXTRA_DIST = TODO PORTING
SUBDIRS = libwdi
if BUILD_EXAMPLES
SUBDIRS += examples
endif
#pkgconfigdir=$(libdir)/pkgconfig
#pkgconfig_DATA=libusb-1.0.pc
#.PHONY: ChangeLog dist-up
#ChangeLog:
# git --git-dir $(top_srcdir)/.git log > ChangeLog || touch ChangeLog
#dist-hook: ChangeLog
reldir = .release/$(distdir)
dist-up: dist
rm -rf $(reldir)
mkdir -p $(reldir)
cp $(distdir).tar.bz2 $(reldir)
rsync -rv $(reldir) dsd_,libusb@frs.sourceforge.net:/home/frs/project/l/li/libusb/libusb-1.0/
rm -rf $(reldir)
@@ -0,0 +1,38 @@
libwdi: Windows Driver Installer library for USB devices
Features:
- Automated driverless device detection
- Automated inf creation, using the name reported by the USB device
- Automated driver files extraction, for both 32 and 64 bit platforms
- Automated driver installation, including UAC elevation where necessary
- When statically linked, only the final executable needs to be redistributed to
ensure that a driver can be automatically installed on any Windows platform.
For the reditributale library to work on both 64 and 32 bit, you must use a
compiler that can produce both 32 and 64 bit binaries, and compile the library
as 32 bit.
For gcc, that means that your compiler should support both the -m32 and -m64
options, and for Visual Studio, that means using a non Express version.
Note that you still have the possibility to use other compilers to produce a 32
bit (or 64 bit) only library, and automated configuration will be smart enough
to detect this, and compile/embed only the required 32 or 64 bit resources.
If you want to compile a 64 bit only library, make sure you comment OPT_M32 in
config.h, or use the --disable-32bit option when runing configure.
For gcc, the best solution right now, to have -m32 and -m64 with very little
effort, is to download WPG System 64 from http://www.cadforte.com/system64.html
as the MinGW-32 and cygwin only compile 32 bit binaries by default, and the
official binary packages from MinGW-w64 don't have multilib enabled, so they are
64 bit only.
Compiling:
Regardless of your development environment, you must either have the Windows DDK
installed, or have the winusb/wdf 32 and 64 bit redistributable DLLs.
On cygwin/mingw, you need to supply the path to your DDK with the --with-ddkdir
option when calling configure (see autogen.sh).
For MSVC, you must edit msvc/config.h and set DDK_PATH path accordingly.
Dependencies:
The Zadig GUI application uses a slightly modified version of libconfig 1.4.5
(LGPL v2.1), which is copyright Mark Lindner et al.
See http://www.hyperrealm.com/libconfig/ for details.
@@ -0,0 +1,17 @@
#!/bin/sh
# use glibtoolize if it is available (darwin)
(glibtoolize --version) < /dev/null > /dev/null 2>&1 && LIBTOOLIZE=glibtoolize || LIBTOOLIZE=libtoolize
$LIBTOOLIZE --copy --force || exit 1
# Force ltmain's NLS test to set locale to C always. Prevents an
# issue when compiling shared libs with MinGW on Chinese locale.
type -P sed &>/dev/null || { echo "sed command not found. Aborting." >&2; exit 1; }
sed -e s/\\\\\${\$lt_var+set}/set/g ltmain.sh > lttmp.sh
mv lttmp.sh ltmain.sh
#
aclocal || exit 1
autoheader || exit 1
autoconf || exit 1
automake -a -c || exit 1
./configure --enable-toggable-debug --enable-examples-build --disable-debug --with-ddkdir="E:/WinDDK/7600.16385.0" --with-libusb0="D:/libusb-win32" $*
@@ -0,0 +1,282 @@
AC_INIT([libwdi], [1.0.0], [libusb-devel@lists.sourceforge.net], [libwdi], [http://libusb.org/wiki/windows_backend])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([libwdi/libwdi.c])
AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER([config.h])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_PREREQ([2.50])
AC_PROG_CC
AC_PROG_LIBTOOL
AC_C_INLINE
AM_PROG_CC_C_O
AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
WDF_VER="01009"
AC_DEFINE_UNQUOTED([WDF_VER], ["${WDF_VER}"], [DDK WDF coinstaller version (string)])
AC_ARG_WITH(ddkdir,
AS_HELP_STRING([--with-ddkdir], [embed WinUSB driver files from the following DDK location]),
DDK_DIR=$withval,
DDK_DIR="")
if test "x$DDK_DIR" != "x"; then
AC_DEFINE_UNQUOTED([DDK_DIR], ["${DDK_DIR}"], [embed WinUSB driver files from the following DDK location])
fi
AC_ARG_WITH(libusb0,
AS_HELP_STRING([--with-libusb0], [embed libusb0 driver files from the following location]),
LIBUSB0_DIR=$withval,
LIBUSB0_DIR="")
if test "x$LIBUSB0_DIR" != "x"; then
AC_DEFINE_UNQUOTED([LIBUSB0_DIR], ["${LIBUSB0_DIR}"], [embed libusb0 driver files from the following location])
fi
AC_ARG_WITH(userdir,
AS_HELP_STRING([--with-userdir], [embed user defined driver files from the following location]),
USER_DIR=$withval,
USER_DIR="")
if test "x$USER_DIR" != "x"; then
AC_DEFINE_UNQUOTED([USER_DIR], ["${USER_DIR}"], [embed user defined driver files from the following location])
fi
if test "x$USER_DIR" == "x" -a "x$DDK_DIR" == "x" -a "x$LIBUSB0_DIR" == "x"; then
AC_MSG_ERROR([One of --with-ddkdir, --with-libusb0 or --with-userdir options MUST be provided.])
fi
AC_MSG_CHECKING([development environment])
case $host in
*-mingw*)
AC_MSG_RESULT([MinGW])
AM_CFLAGS="-Wshadow -DWINVER=0x500"
NO_CYGWIN=""
LIBCONFIG_LIBADD=""
LIBCONFIG_CFLAGS=""
;;
*-cygwin*)
AC_MSG_RESULT([cygwin])
AM_CFLAGS="-DWINVER=0x500"
save_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} -mno-cygwin"
AC_MSG_CHECKING([if -mno-cygwin is supported])
AC_TRY_COMPILE(, [;],
has_mno_cygwin=yes,
has_mno_cygwin=no)
if test "x$has_mno_cygwin" == "xyes"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([you must ensure that -mno-cygwin is supported on cygwin])
fi
CFLAGS="${save_CFLAGS}"
# if you try to redefine CC to "gcc -mno-cygwin", all kind of bad things happen
# => use a variable instead
NO_CYGWIN="-mno-cygwin"
LIBCONFIG_LIBADD="-L/lib/mingw -lcrtdll -lmingwex"
LIBCONFIG_CFLAGS="-static -I/usr/include/mingw -D__MINGW_FEATURES__"
;;
*)
AC_MSG_ERROR([unsupported development environment])
esac
AM_LDFLAGS="-no-undefined -avoid-version"
AC_CHECK_TOOL(RC, windres, no)
# 32 bit support
save_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} -m32"
AC_MSG_CHECKING([whether the compiler can produce 32 bit binaries])
AC_TRY_COMPILE(, [;],
compiler_has_m32=yes,
compiler_has_m32=no)
if test "x$compiler_has_m32" == "xyes"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
CFLAGS="${save_CFLAGS}"
# 64 bit support
save_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} -m64"
AC_MSG_CHECKING([whether the compiler can produce 64 bit binaries])
AC_TRY_COMPILE(, [;],
compiler_has_m64=yes,
compiler_has_m64=no)
if test "x$compiler_has_m64" == "xyes"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
CFLAGS="${save_CFLAGS}"
if test "x$compiler_has_m64" != "xyes" -a "x$compiler_has_m32" != "xyes"; then
AC_MSG_ERROR([neither -m32 nor -m64 is supported by your compiler])
fi
# 32 and 64 bit selection
AC_ARG_ENABLE([32bit], [AS_HELP_STRING([--enable-32bit],
[build 32 bit compatible library (default y)])],
[enable_32bit=$enableval],
[enable_32bit='yes'])
AC_ARG_ENABLE([64bit], [AS_HELP_STRING([--enable-64bit],
[build 64 bit compatible library (default y)])],
[enable_64bit='$enableval'],
[enable_64bit='yes'])
AC_ARG_ENABLE([ia64], [AS_HELP_STRING([--enable-ia64],
[embed IA64/Itanium driver files (default n)])],
[enable_ia64='$enableval'],
[enable_ia64='no'])
if test "x$enable_64bit" == "xno" -a "x$enable_32bit" == "xno"; then
AC_MSG_ERROR([you cannot disable both 32 and 64 bit support])
fi
# OK, let's make some sense of all this 32/64 bit mess...
if test "x$enable_64bit" != "xno" -a "x$compiler_has_m64" == "xno"; then
if test "x$enable_32bit" == "xno"; then
AC_MSG_ERROR([compiler cannot produce 64 bit binaries, and 32 bit support is disabled])
fi
AC_MSG_WARN([compiler cannot produce 64 bit binaries - disabling 64 bit support])
enable_64bit="no"
fi
if test "x$enable_32bit" != "xno" -a "x$compiler_has_m32" == "xno"; then
if test "x$enable_64bit" == "xno"; then
AC_MSG_ERROR([compiler cannot produce 32 bit binaries, and 64 bit support is disabled])
fi
AC_MSG_WARN([compiler cannot produce 32 bit binaries - disabling 32 bit support])
enable_32bit="no"
fi
# define the automake and config.h variables
if test "x$enable_32bit" != "xno"; then
AC_DEFINE([OPT_M32], [], [32 bit support])
AC_SUBST(OPT_M32)
fi
AM_CONDITIONAL([OPT_M32], [test "x$enable_32bit" != "xno"])
if test "x$enable_64bit" != "xno"; then
AC_DEFINE([OPT_M64], [], [64 bit support])
AC_SUBST(OPT_M64)
fi
AM_CONDITIONAL([OPT_M64], [test "x$enable_64bit" != "xno"])
if test "x$enable_ia64" != "xno"; then
AC_DEFINE([OPT_IA64], [], [embed IA64 driver files])
AC_SUBST(OPT_IA64)
fi
if test "x$enable_64bit" != "xno"; then
# the default is to produce 32 bit, when both 64 and 32 bit support are available
if test "x$enable_32bit" != "xno"; then
AC_MSG_NOTICE([will produce 32 bit library and samples, compatible with 64 bit platforms])
AC_MSG_NOTICE([if you want to produce 64 bit only library and samples, use --disable-32bit])
ARCH_CFLAGS="-m32"
ARCH_RCFLAGS="--target=pe-i386"
else
AC_MSG_WARN([will produce a 64 bit library that is INCOMPATIBLE with 32 bit platforms])
ARCH_CFLAGS="-m64 -D_WIN64"
ARCH_RCFLAGS=""
fi
else
AC_MSG_WARN([will produce a 32 bit library that is INCOMPATIBLE with 64 bit platforms])
ARCH_CFLAGS=""
ARCH_RCFLAGS=""
fi
AC_SUBST([ARCH_CFLAGS])
AC_SUBST([ARCH_RCFLAGS])
if test "x$DDK_DIR" != "x"; then
# check that the required WinUSB DDK files are available
if test "x$enable_64bit" != "xno"; then
# NB: I found the hard way that cygwin doesn't like multiple files to be provided on multiple lines - YOU HAVE BEEN WARNED!
AC_CHECK_FILES([$DDK_DIR/redist/wdf/amd64/WdfCoInstaller${WDF_VER}.dll $DDK_DIR/redist/winusb/amd64/winusbcoinstaller2.dll],,
[AC_MSG_ERROR([the WinUSB amd64 driver files could not be detected (--with-ddkdir)])])
fi
if test "x$enable_32bit" != "xno"; then
AC_CHECK_FILES([$DDK_DIR/redist/wdf/x86/WdfCoInstaller${WDF_VER}.dll $DDK_DIR/redist/winusb/x86/winusbcoinstaller2.dll],,
[AC_MSG_ERROR([the WinUSB x86 driver files could not be detected (--with-ddkdir)])])
fi
if test "x$enable_ia64" != "xno"; then
AC_CHECK_FILES([$DDK_DIR/redist/wdf/ia64/WdfCoInstaller${WDF_VER}.dll $DDK_DIR/redist/winusb/ia64/winusbcoinstaller2.dll],,
[AC_MSG_ERROR([the WinUSB ia64 driver files could not be detected (--with-ddkdir)])])
fi
fi
if test "x$LIBUSB0_DIR" != "x"; then
# check that the required libusb0 driver files are available
AC_CHECK_FILES([$LIBUSB0_DIR/bin/x86/libusb0.sys $LIBUSB0_DIR/bin/x86/libusb0_x86.dll],,
[AC_MSG_ERROR([the libusb0 x86 driver files could not be detected (--with-libusb0)])])
if test "x$enable_64bit" != "xno"; then
AC_CHECK_FILES([$LIBUSB0_DIR/bin/amd64/libusb0.sys $LIBUSB0_DIR/bin/amd64/libusb0.dll],,
[AC_MSG_ERROR([the libusb0 amd64 driver files could not be detected (--with-libusb0)])])
fi
if test "x$enable_ia64" != "xno"; then
AC_CHECK_FILES([$LIBUSB0_DIR/bin/ia64/libusb0.sys $LIBUSB0_DIR/bin/ia64/libusb0.dll],,
[AC_MSG_ERROR([the libusb0 ia64 driver files could not be detected (--with-libusb0)])])
fi
fi
if test "x$USER_DIR" != "x"; then
AC_CHECK_FILE([$USER_DIR],,[AC_MSG_ERROR([the custom driver directory could not be detected (--with-userdir)])])
fi
# Message logging
AC_ARG_ENABLE([log], [AS_HELP_STRING([--enable-log], [enable logging (default y)])],
[log_enabled=$enableval],
[log_enabled='yes'])
if test "x$log_enabled" != "xno"; then
AC_DEFINE([ENABLE_LOGGING], 1, [Message logging])
fi
AC_ARG_ENABLE([debug-log], [AS_HELP_STRING([--enable-debug-log],
[force debug logging always (default n)])],
[debug_log_enabled=$enableval],
[debug_log_enabled='no'])
AC_ARG_ENABLE([toggable-debug], [AS_HELP_STRING([--enable-toggable-debug],
[enable switchable debug logging (default n)])],
[toggable_debug=$enableval],
[toggable_debug='no'])
if test "x$debug_log_enabled" != "xno"; then
AC_DEFINE([ENABLE_DEBUG_LOGGING], 1, [Debug message logging (forced)])
else
if test "x$toggable_debug" != "xno"; then
AC_DEFINE([INCLUDE_DEBUG_LOGGING], 1, [Debug message logging (toggable)])
fi
fi
# --enable-debug : check whether they want to have debug symbols:
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [include debug symbols for gdb (default y)]),
[debug_enabled=$enableval],
[debug_enabled='yes'])
if test "x$debug_enabled" = "xyes" ; then
CFLAGS="-g -O2"
else
CFLAGS="-O2"
fi
# Examples build
AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build],
[build example applications (default n)])],
[build_examples=$enableval],
[build_examples='no'])
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
# check for -Wno-pointer-sign compiler support (GCC >= 4)
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -Wno-pointer-sign"
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
nopointersign_cflags="-Wno-pointer-sign", nopointersign_cflags="")
CFLAGS="$saved_cflags"
AM_CFLAGS="$AM_CFLAGS -std=gnu99 -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags"
AC_SUBST(VISIBILITY_CFLAGS)
AC_SUBST(AM_CFLAGS)
AC_SUBST(AM_LDFLAGS)
AC_SUBST(NO_CYGWIN)
AC_SUBST(LIBCONFIG_CFLAGS)
AC_SUBST(LIBCONFIG_LIBADD)
AC_CONFIG_FILES([Makefile] [libwdi/Makefile] [examples/libconfig/Makefile] [examples/Makefile])
AC_OUTPUT
@@ -0,0 +1,196 @@
@rem default builds static library.
@rem you can pass the following arguments (case insensitive):
@rem - "DLL" to build a DLL instead of a static library
@rem - "no_samples" to build the library only
@echo off
if Test%BUILD_ALT_DIR%==Test goto usage
rem process commandline parameters
set TARGET=LIBRARY
set BUILD_SAMPLES=YES
:more_args
if "%1" == "" goto no_more_args
rem /I for case insensitive
if /I Test%1==TestDLL set TARGET=DYNLINK
if /I Test%1==Testno_samples set BUILD_SAMPLES=NO
rem - shift the arguments and examine %1 again
shift
goto more_args
:no_more_args
set DDK_DIR=%BASEDIR:\=\\%
set ORG_BUILD_ALT_DIR=%BUILD_ALT_DIR%
set ORG_BUILDARCH=%_BUILDARCH%
set ORG_PATH=%PATH%
set ORG_BUILD_DEFAULT_TARGETS=%BUILD_DEFAULT_TARGETS%
set version=1.0
set cpudir=i386
if %ORG_BUILDARCH%==x86 goto isI386
set cpudir=amd64
echo #define BUILD64> libwdi\build64.h
goto main_start
:isI386
echo #define NO_BUILD64> libwdi\build64.h
:main_start
cd libwdi
set srcPath=obj%BUILD_ALT_DIR%\%cpudir%
del Makefile.hide >NUL 2>&1
if EXIST Makefile ren Makefile Makefile.hide
set 386=1
set AMD64=
set BUILD_DEFAULT_TARGETS=-386
set _AMD64bit=
set _BUILDARCH=x86
set PATH=%BASEDIR%\bin\x86;%BASEDIR%\bin\x86\x86
copy embedder_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\i386\embedder.exe . >NUL 2>&1
copy installer_x86_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\i386\installer_x86.exe . >NUL 2>&1
set 386=
set AMD64=1
set BUILD_DEFAULT_TARGETS=-amd64
set _AMD64bit=true
set _BUILDARCH=AMD64
set PATH=%BASEDIR%\bin\x86\amd64;%BASEDIR%\bin\x86
copy installer_x64_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\amd64\installer_x64.exe . >NUL 2>&1
if %ORG_BUILDARCH%==AMD64 goto restorePath
set 386=1
set AMD64=
set BUILD_DEFAULT_TARGETS=-386
set _AMD64bit=
set _BUILDARCH=x86
:restorePath
set PATH=%ORG_PATH%
echo.
echo Embedding binary resources
embedder.exe embedded.h
rem DLL or static lib selection (must use concatenation)
echo TARGETTYPE=%TARGET% > target
copy target+libwdi_sources sources >NUL 2>&1
del target
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\%cpudir%\libwdi.lib . >NUL 2>&1
copy obj%BUILD_ALT_DIR%\%cpudir%\libwdi.dll . >NUL 2>&1
if EXIST Makefile.hide ren Makefile.hide Makefile
cd ..
if Test%BUILD_SAMPLES%==TestNO goto done
cd examples\getopt
del Makefile.hide >NUL 2>&1
if EXIST Makefile ren Makefile Makefile.hide
copy getopt_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\%cpudir%\getopt.lib . >NUL 2>&1
if EXIST Makefile.hide ren Makefile.hide Makefile
cd ..\libconfig
del Makefile.hide >NUL 2>&1
if EXIST Makefile ren Makefile Makefile.hide
copy libconfig_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\%cpudir%\libconfig.lib . >NUL 2>&1
if EXIST Makefile.hide ren Makefile.hide Makefile
cd ..
del Makefile.hide >NUL 2>&1
if EXIST Makefile ren Makefile Makefile.hide
copy zadic_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\%cpudir%\zadic.exe . >NUL 2>&1
rem Work around MS's VC++ and DDK weird icompatibilities wth regards to rc files
echo #include ^<windows.h^> > afxres.h
echo #ifndef IDC_STATIC >> afxres.h
echo #define IDC_STATIC -1 >> afxres.h
echo #endif >> afxres.h
copy zadig_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
del afxres.h
copy obj%BUILD_ALT_DIR%\%cpudir%\zadig.exe . >NUL 2>&1
copy inf_wizard_sources sources >NUL 2>&1
@echo on
build -cwgZ
@echo off
if errorlevel 1 goto builderror
copy obj%BUILD_ALT_DIR%\%cpudir%\inf-wizard.exe . >NUL 2>&1
if EXIST Makefile.hide ren Makefile.hide Makefile
cd ..
goto done
:builderror
if EXIST Makefile.hide ren Makefile.hide Makefile
if EXIST afxres.h del afxres.h
cd ..
echo Build failed
goto done
:usage
echo ddk_build must be run in a Windows Driver Kit build environment
pause
goto done
:done
set BUILD_ALT_DIR=%ORG_BUILD_ALT_DIR%
set _BUILDARCH=%ORG_BUILDARCH%
set PATH=%ORG_PATH%
set BUILD_DEFAULT_TARGETS=%ORG_BUILD_DEFAULT_TARGETS%
if Test%DDK_TARGET_OS%==TestWinXP goto nowarn
echo.
echo.
echo WARNING: You do not seem to use the Windows XP DDK build environment.
echo Be mindful that using the Windows Vista or Windows 7 DDK build environments
echo will result in library and applications that do NOT run on Windows XP.
echo.
:nowarn
@@ -0,0 +1,45 @@
INCLUDES = -I$(top_srcdir)
BUILT_SOURCES = embedded.h
noinst_PROGRAMS = embedder
noinst_EXES = embedder.exe
lib_LTLIBRARIES = libwdi.la
LIB_SRC = resource.h logging.h tokenizer.h installer.h libwdi.h logging.c tokenizer.c vid_data.c libwdi_dlg.c libwdi.c
if OPT_M32
noinst_PROGRAMS += installer_x86
noinst_EXES += installer_x86.exe
installer_x86_SOURCES = installer.h installer.c
installer_x86_CFLAGS = -m32 $(NO_CYGWIN) $(AM_CFLAGS)
installer_x86_LDFLAGS = $(NO_CYGWIN) $(AM_LDFLAGS) -static
installer_x86_LDADD = -lsetupapi -lnewdev
endif
if OPT_M64
noinst_PROGRAMS += installer_x64
noinst_EXES += installer_x64.exe
installer_x64_CC = gcc $(NO_CYGWIN)
installer_x64_SOURCES = installer.h installer.c
installer_x64_CFLAGS = -m64 -D_WIN64 $(NO_CYGWIN) $(AM_CFLAGS)
installer_x64_LDFLAGS = $(NO_CYGWIN) $(AM_LDFLAGS) -static
installer_x64_LDADD = -lsetupapi -lnewdev
endif
embedder_SOURCES = embedder.h embedder_files.h embedder.c
embedder_LDADD = -lversion
EXTRA_DIST = $(LIB_SRC)
libwdi_rc.lo: libwdi.rc
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(RC) $(ARCH_RCFLAGS) -i $< -o $@
libwdi_la_CFLAGS = $(ARCH_CFLAGS) $(NO_CYGWIN) $(VISIBILITY_CFLAGS) $(AM_CFLAGS)
libwdi_la_LDLAGS = $(NO_CYGWIN) $(AM_LDFLAGS)
libwdi_la_LIBADD = libwdi_rc.lo -lsetupapi -lole32
libwdi_la_SOURCES = $(LIB_SRC)
embedded.h: $(noinst_EXES)
./embedder.exe embedded.h
clean-local:
-rm -rf embedded.h
@@ -0,0 +1 @@
#define NO_BUILD64
@@ -0,0 +1,406 @@
/*
* embedder : converts binary resources into a .h include
* "If you can think of a better way to get ice, I'd like to hear it."
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This tool is meant to be call as a pre-built event when compiling the
* installer library, to produce a .h that embeds all the necessary driver
* binary resources.
*
* This is required work around the many limitations of resource files, as
* well as the impossibility to force the MS linker to embed resources always
* with a static library (unless the library is split into .res + .lib)
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <config.h>
#include <stdint.h>
#include "embedder.h"
#include "embedder_files.h"
#define safe_free(p) do {if (p != NULL) {free(p); p = NULL;}} while(0)
#if defined(__CYGWIN__ )
#include <libgen.h> // for basename()
#define _MAX_FNAME 256
#define _MAX_EXT 256
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
// Hack a _splitpath() for cygwin, according to our *very specific* needs
void __inline _splitpath(char *path, char *drive, char *dir, char *fname, char *ext) {
strncpy(fname, basename(path), _MAX_FNAME);
ext[0] = 0;
}
#endif
const int nb_embeddables_fixed = sizeof(embeddable_fixed)/sizeof(struct emb);
int nb_embeddables;
struct emb* embeddable = embeddable_fixed;
#if defined(USER_DIR)
char initial_dir[] = USER_DIR;
#endif
void dump_buffer_hex(FILE* fd, unsigned char *buffer, size_t size)
{
size_t i;
// Make sure we output something even if the original file is empty
if (size == 0) {
fprintf(fd, "0x00");
}
for (i=0; i<size; i++) {
if (!(i%0x10))
fprintf(fd, "\n\t");
fprintf(fd, "0x%02X,", buffer[i]);
}
fprintf(fd, "\n");
}
#if defined(USER_DIR)
// Modified from http://www.zemris.fer.hr/predmeti/os1/misc/Unix2Win.htm
void ScanDir(char *dirname, BOOL countfiles)
{
BOOL fFinished;
HANDLE hList;
TCHAR szDir[MAX_PATH+1];
TCHAR szSubDir[MAX_PATH+1];
WIN32_FIND_DATA FileData;
// Get the proper directory path
sprintf(szDir, "%s\\%s\\*", initial_dir, dirname);
// Get the first file
hList = FindFirstFile(szDir, &FileData);
if (hList == INVALID_HANDLE_VALUE) {
return;
}
// Traverse through the directory structure
fFinished = FALSE;
while (!fFinished) {
// Check the object is a directory or not
if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ( (strcmp(FileData.cFileName, ".") != 0)
&& (strcmp(FileData.cFileName, "..") != 0)) {
// Get the full path for sub directory
sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName);
ScanDir(szSubDir, countfiles);
}
} else {
if (!countfiles) {
if ( (embeddable[nb_embeddables].file_name =
malloc(strlen(initial_dir) + strlen(dirname) +
strlen(FileData.cFileName) + 2) ) == NULL) {
return;
}
if ( (embeddable[nb_embeddables].extraction_subdir =
malloc(strlen(dirname)) ) == NULL) {
return;
}
sprintf(embeddable[nb_embeddables].file_name,
"%s%s\\%s", initial_dir, dirname, FileData.cFileName );
if (dirname[0] == '\\') {
sprintf(embeddable[nb_embeddables].extraction_subdir,
"%s", dirname+1);
} else {
safe_free(embeddable[nb_embeddables].extraction_subdir);
embeddable[nb_embeddables].extraction_subdir = _strdup(".");
}
}
nb_embeddables++;
}
if (!FindNextFile(hList, &FileData)) {
if (GetLastError() == ERROR_NO_MORE_FILES) {
fFinished = TRUE;
}
}
}
FindClose(hList);
}
void add_user_files(void) {
int i;
// Switch slashes to backslashes
for (i=0; i<(int)strlen(initial_dir); i++) {
if (initial_dir[i] == '/') {
initial_dir[i] = '\\';
}
}
// Dry run to count additional files
ScanDir("", TRUE);
if (nb_embeddables == nb_embeddables_fixed) {
fprintf(stderr, "No user embeddable files found.\n");
return;
}
// Extend the array to add the user files
embeddable = calloc(nb_embeddables, sizeof(struct emb));
if (embeddable == NULL) {
fprintf(stderr, "Could not include user embeddable files.\n");
return;
}
// Copy the fixed part of our table into our new array
for (i=0; i<nb_embeddables_fixed; i++) {
embeddable[i].file_name = embeddable_fixed[i].file_name;
embeddable[i].extraction_subdir = embeddable_fixed[i].extraction_subdir;
}
nb_embeddables = nb_embeddables_fixed;
// Fill in the array
ScanDir("", FALSE);
}
#endif
int __cdecl main (int argc, char *argv[])
{
int ret, i, j, drv_index;
DWORD r, version_size;
void* version_buf;
UINT junk;
VS_FIXEDFILEINFO *file_info, drv_info[2] = { {0}, {0} };
WIN32_FIND_DATA file_data;
SYSTEMTIME file_date;
size_t size;
size_t* file_size;
FILE *fd, *header_fd;
HANDLE header_handle = INVALID_HANDLE_VALUE, file_handle = INVALID_HANDLE_VALUE;
FILETIME header_time, file_time;
BOOL rebuild = TRUE;
char internal_name[] = "file_###";
unsigned char* buffer;
char fullpath[MAX_PATH];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
// Disable stdout bufferring
setvbuf(stdout, NULL, _IONBF,0);
if (argc != 2) {
fprintf(stderr, "You must supply a header name\n");
return 1;
}
nb_embeddables = nb_embeddables_fixed;
#if defined(USER_DIR)
add_user_files();
#endif
// Check if any of the embedded files have changed
header_handle = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (header_handle != INVALID_HANDLE_VALUE) {
// Header already exists
header_time.dwHighDateTime = 0; header_time.dwLowDateTime = 0;
GetFileTime(header_handle, NULL, NULL, &header_time);
rebuild = FALSE;
for (i=0; ; i++) {
if (file_handle != INVALID_HANDLE_VALUE) {
CloseHandle(file_handle);
file_handle = INVALID_HANDLE_VALUE;
}
if ( (i>=nb_embeddables) || (rebuild) )
break;
file_handle = CreateFileA(embeddable[i].file_name, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if (file_handle != INVALID_HANDLE_VALUE) {
file_time.dwHighDateTime = 0; file_time.dwLowDateTime = 0;
GetFileTime(file_handle, NULL, NULL, &file_time);
if (CompareFileTime(&header_time, &file_time) <= 0) {
rebuild = TRUE;
break;
}
}
}
CloseHandle(header_handle);
}
if (!rebuild) {
printf(" resources haven't changed - skipping step\n");
return 0;
}
size = sizeof(size_t)*nb_embeddables;
file_size = malloc(size);
if (file_size == NULL) {
fprintf(stderr, "Couldn't even allocate a measly %d bytes\n", (int)size);
return 1;
}
header_fd = fopen(argv[1], "w");
if (header_fd == NULL) {
fprintf(stderr, "Can't create file '%s'\n", argv[1]);
ret = 1;
goto out1;
}
fprintf(header_fd, "#pragma once\n");
for (i=0; i<nb_embeddables; i++) {
r = GetFullPathNameA(embeddable[i].file_name, MAX_PATH, fullpath, NULL);
if ((r == 0) || (r > MAX_PATH)) {
fprintf(stderr, "Unable to get full path for %s\n", embeddable[i].file_name);
ret = 1;
goto out2;
}
printf("Embedding '%s' ", fullpath);
fd = fopen(embeddable[i].file_name, "rb");
if (fd == NULL) {
fprintf(stderr, "Couldn't open file '%s'\n", fullpath);
ret = 1;
goto out2;
}
// Identify the WinUSB and libusb0 files we'll pick the date & version of
for (j=(int)strlen(embeddable[i].file_name); j>=0; j--) {
if (embeddable[i].file_name[j] == '\\') break;
}
drv_index = -1;
if (strcmp(&embeddable[i].file_name[j+1], "winusbcoinstaller2.dll") == 0) {
drv_index = 0;
} else if (strcmp(&embeddable[i].file_name[j+1], "libusb0.sys") == 0) {
drv_index = 1;
}
// Read the creation date (once more)
file_data.ftCreationTime.dwHighDateTime = 0;
file_data.ftCreationTime.dwLowDateTime = 0;
if ( (FindFirstFileA(fullpath, &file_data) != INVALID_HANDLE_VALUE)
&& (FileTimeToSystemTime(&file_data.ftCreationTime, &file_date)) ) {
printf("(%04d.%02d.%02d", file_date.wYear, file_date.wMonth, file_date.wDay);
}
// Read the version
version_size = GetFileVersionInfoSizeA(fullpath, NULL);
version_buf = malloc(version_size);
if (version_buf != NULL) {
if ( (GetFileVersionInfoA(fullpath, 0, version_size, version_buf))
&& (VerQueryValueA(version_buf, "\\", (void*)&file_info, &junk)) ) {
printf(", v%d.%d.%d.%d)", (int)file_info->dwFileVersionMS>>16, (int)file_info->dwFileVersionMS&0xFFFF,
(int)file_info->dwFileVersionLS>>16, (int)file_info->dwFileVersionLS&0xFFFF);
if ( (drv_index != -1) && (drv_info[drv_index].dwSignature == 0) ) {
printf("*");
memcpy(&drv_info[drv_index], file_info, sizeof(VS_FIXEDFILEINFO));
drv_info[drv_index].dwFileDateLS = file_data.ftCreationTime.dwLowDateTime;
drv_info[drv_index].dwFileDateMS = file_data.ftCreationTime.dwHighDateTime;
}
} else {
printf(")");
}
free(version_buf);
}
printf("\n");
fseek(fd, 0, SEEK_END);
size = (size_t)ftell(fd);
fseek(fd, 0, SEEK_SET);
file_size[i] = size;
buffer = (unsigned char*) malloc(size);
if (buffer == NULL) {
fprintf(stderr, "Couldn't allocate buffer");
ret = 1;
goto out3;
}
if (fread(buffer, 1, size, fd) != size) {
fprintf(stderr, "Read error");
ret = 1;
goto out4;
}
fclose(fd);
_snprintf(internal_name, sizeof(internal_name), "file_%03X", (unsigned char)i);
fprintf(header_fd, "const unsigned char %s[] = {", internal_name);
dump_buffer_hex(header_fd, buffer, size);
fprintf(header_fd, "};\n\n");
safe_free(buffer);
fclose(fd);
}
fprintf(header_fd, "struct res {\n" \
"\tchar* subdir;\n" \
"\tchar* name;\n" \
"\tsize_t size;\n" \
"\tconst unsigned char* data;\n" \
"};\n\n");
fprintf(header_fd, "const struct res resource[] = {\n");
for (i=0; i<nb_embeddables; i++) {
fname[0] = 0;
_splitpath(embeddable[i].file_name, NULL, NULL, fname, ext);
strncat(fname, ext, sizeof(fname)-strlen(fname));
_snprintf(internal_name, sizeof(internal_name), "file_%03X", (unsigned char)i);
fprintf(header_fd, "\t{ \"");
// We need to handle backslash sequences
for (j=0; j<(int)strlen(embeddable[i].extraction_subdir); j++) {
fputc(embeddable[i].extraction_subdir[j], header_fd);
if (embeddable[i].extraction_subdir[j] == '\\') {
fputc('\\', header_fd);
}
}
fprintf(header_fd, "\", \"%s\", %d, %s },\n",
fname, (int)file_size[i], internal_name);
}
fprintf(header_fd, "};\n");
fprintf(header_fd, "const int nb_resources = sizeof(resource)/sizeof(resource[0]);\n\n");
// These will be used to populate the inf data
fprintf(header_fd, "// WinUSB = 0, libusb0 = 1\n");
fprintf(header_fd, "const VS_FIXEDFILEINFO driver_version[2] = {\n");
for (i=0; i<2; i++) {
fprintf(header_fd, " { 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X,\n",
(uint32_t)drv_info[i].dwSignature, (uint32_t)drv_info[i].dwStrucVersion, (uint32_t)drv_info[i].dwFileVersionMS,
(uint32_t)drv_info[i].dwFileVersionLS, (uint32_t)drv_info[i].dwProductVersionMS,
(uint32_t)drv_info[i].dwProductVersionLS, (uint32_t)drv_info[i].dwFileFlagsMask);
fprintf(header_fd, " 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X},\n",
(uint32_t)drv_info[i].dwFileFlags, (uint32_t)drv_info[i].dwFileOS, (uint32_t)drv_info[i].dwFileType,
(uint32_t)drv_info[i].dwFileSubtype, (uint32_t)drv_info[i].dwFileDateMS, (uint32_t)drv_info[i].dwFileDateLS);
}
fprintf(header_fd, "};\n");
fclose(header_fd);
safe_free(file_size);
#if defined(USER_DIR)
for (i=nb_embeddables_fixed; i<nb_embeddables; i++) {
safe_free(embeddable[i].extraction_subdir);
safe_free(embeddable[i].file_name);
}
if (embeddable != embeddable_fixed) {
safe_free(embeddable);
}
#endif
return 0;
out4:
safe_free(buffer);
out3:
fclose(fd);
out2:
fclose(header_fd);
// Must delete a failed file so that Make can relaunch its build
DeleteFile(argv[1]);
out1:
safe_free(file_size);
return ret;
}
@@ -0,0 +1,66 @@
/*
* embedder : converts binary resources into a .h include
* "If you can think of a better way to get ice, I'd like to hear it."
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#if !defined(OPT_M32) && !defined(OPT_M64)
#error both 32 and 64 bit support have been disabled - check your config.h
#endif
#if !defined(DDK_DIR) && !defined(LIBUSB0_DIR) && !defined(USER_DIR)
#error at least one of DDK_DIR, LIBUSB0_DIR or USER_DIR must be defined - check your config.h
#endif
// Some adjustment is needed for MSVC
#if defined(_MSC_VER)
// Because the embedder is compiled as 32 bit always, we detect
// 64 bit MS compilations through an additional include
#include "build64.h"
#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#if (defined(_WIN64) || defined(BUILD64)) && defined(OPT_M32)
// a 64 bit application/library CANNOT be used on 32 bit platforms
#pragma message(__FILE__ "(" __STR1__(__LINE__) ") : warning : library is compiled as 64 bit - disabling 32 bit support")
#undef OPT_M32
#endif
#endif
/*
* Defines where we should we pick the 32 and 64 bit installer exes to embed
*/
#if defined(_MSC_VER) && !defined(DDKBUILD)
#if !defined(SOLUTIONDIR)
#define SOLUTIONDIR ".."
#endif
#if defined(_DEBUG)
#define INSTALLER_PATH_32 SOLUTIONDIR "\\Win32\\Debug\\helper"
#define INSTALLER_PATH_64 SOLUTIONDIR "\\x64\\Debug\\helper"
#else
#define INSTALLER_PATH_32 SOLUTIONDIR "\\Win32\\Release\\helper"
#define INSTALLER_PATH_64 SOLUTIONDIR "\\x64\\Release\\helper"
#endif
#else
#if !defined(SOLUTIONDIR)
#define SOLUTIONDIR "."
#endif
// If you compile with shared libs, DON'T PICK THE EXE IN "installer",
// as it won't run from ANYWHERE ELSE! Use the one from .libs instead.
#define INSTALLER_PATH_32 SOLUTIONDIR
#define INSTALLER_PATH_64 SOLUTIONDIR
#endif
@@ -0,0 +1,206 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="embedder"
ProjectGUID="{792D44D5-28A7-4EB3-B84B-8021FE3189F9}"
RootNamespace="embedder"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper\$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
BuildLogFile="$(IntDir)\$(ProjectName).htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;USER_DIR=\&quot;\&quot;;OPT_M32;OPT_M64;SOLUTIONDIR=\&quot;..\\..\\..\&quot;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="version.lib"
LinkIncremental="2"
AdditionalLibraryDirectories=""
GenerateDebugInformation="true"
ProgramDatabaseFile="$(TargetDir)$(ProjectName).pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper\$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
BuildLogFile="$(IntDir)\$(ProjectName).htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;USER_DIR=\&quot;\&quot;;OPT_M32;OPT_M64;SOLUTIONDIR=\&quot;..\\..\\..\&quot;"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories=""
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{AF571DD9-AF6B-4F0A-9A9E-D041D12982F7}"
>
<File
RelativePath=".\embedder.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
>
<File
RelativePath="..\msvc\config.h"
>
</File>
<File
RelativePath=".\embedder.h"
>
</File>
<File
RelativePath=".\embedder_files.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>embedder</ProjectName>
<ProjectGuid>{792D44D5-28A7-4EB3-B84B-8021FE3189F9}</ProjectGuid>
<RootNamespace>embedder</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\$(ProjectName)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\$(ProjectName)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;USER_DIR="";OPT_M32;OPT_M64;SOLUTIONDIR="..\\..\\..";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(TargetDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;USER_DIR="";OPT_M32;OPT_M64;SOLUTIONDIR="..\\..\\..";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="embedder.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\msvc\config.h" />
<ClInclude Include="embedder.h" />
<ClInclude Include="embedder_files.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{AF571DD9-AF6B-4F0A-9A9E-D041D12982F7}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{73d653ba-adc0-4b92-812a-573971d03d26}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="embedder.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\msvc\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="embedder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="embedder_files.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
@@ -0,0 +1,90 @@
/*
* embedder : converts binary resources into a .h include
* "If you can think of a better way to get ice, I'd like to hear it."
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
/*
* This include defines the driver files that should be embedded in the library
* If you want to add extra files from a specific directory (eg signed inf and cat)
* you should either define the macro USER_DIR in msvc/config.h (MS compilers) or
* use the --with-userdir option when running configure.
*/
struct emb {
char* file_name;
char* extraction_subdir;
};
/*
* files to embed
*/
struct emb embeddable_fixed[] = {
// 32 bit driver files
#if defined(OPT_M32)
#if defined(DDK_DIR)
{ DDK_DIR "\\redist\\wdf\\x86\\WdfCoInstaller" WDF_VER ".dll", "x86" },
{ DDK_DIR "\\redist\\winusb\\x86\\winusbcoinstaller2.dll", "x86" },
#endif
{ INSTALLER_PATH_32 "\\installer_x86.exe", "." },
#endif
// 64 bit driver files
#if defined(OPT_M64)
#if defined(DDK_DIR)
{ DDK_DIR "\\redist\\wdf\\amd64\\WdfCoInstaller" WDF_VER ".dll", "amd64" },
{ DDK_DIR "\\redist\\winusb\\amd64\\winusbcoinstaller2.dll", "amd64" },
#endif
#if defined(LIBUSB0_DIR)
{ LIBUSB0_DIR "\\bin\\amd64\\libusb0.dll", "amd64" },
{ LIBUSB0_DIR "\\bin\\amd64\\libusb0.sys", "amd64" },
#endif
{ INSTALLER_PATH_64 "\\installer_x64.exe", "." },
#endif
// IA64 (Itanium) driver files
#if defined(OPT_IA64)
#if defined(DDK_DIR)
{ DDK_DIR "\\redist\\wdf\\ia64\\WdfCoInstaller" WDF_VER ".dll", "ia64" },
{ DDK_DIR "\\redist\\winusb\\ia64\\winusbcoinstaller2.dll", "ia64" },
#endif
#if defined(LIBUSB0_DIR)
{ LIBUSB0_DIR "\\bin\\ia64\\libusb0.dll", "ia64" },
{ LIBUSB0_DIR "\\bin\\ia64\\libusb0.sys", "ia64" },
#endif
#endif
// Common driver files
// On 64 bit, for WOW64, we must include the 32 bit libusb0 files as well
#if defined(LIBUSB0_DIR)
{ LIBUSB0_DIR "\\bin\\x86\\libusb0_x86.dll", "x86" },
{ LIBUSB0_DIR "\\bin\\x86\\libusb0.sys", "x86" },
{ LIBUSB0_DIR "\\installer_license.txt", "license\\libusb-win32" },
{ LIBUSB0_DIR "\\bin\\libusb-win32-bin-README.txt", ".\\" },
#endif
#if defined(DDK_DIR)
{ DDK_DIR "\\license.rtf", "license\\WinUSB" }, // WinUSB License file
#endif
// inf templates for the tokenizer ("" directory means no extraction)
{ "winusb.inf.in", "" },
{ "libusb-win32.inf.in", "" },
};
@@ -0,0 +1,20 @@
TARGETNAME=embedder
TARGETTYPE=PROGRAM
!IFNDEF MSC_WARNING_LEVEL
MSC_WARNING_LEVEL=/W3
!ENDIF
USE_MSVCRT=1
UMTYPE=console
UMBASE=0x01000000
INCLUDES=..\msvc;$(DDK_INC_PATH)
C_DEFINES = $(C_DEFINES) /DDDKBUILD
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\version.lib
SOURCES=embedder.c
@@ -0,0 +1,681 @@
/*
* Library for WinUSB/libusb automated driver installation
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
// This standalone installer is a separate exe, as it needs
// - administrative rights, and therefore UAC elevation on platforms that use UAC
// - native 32 or 64 bit execution according to the platform
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <setupapi.h>
#include <process.h>
#include <sddl.h>
#include "installer.h"
#include "libwdi.h"
#include "msapi_utf8.h"
// DDK complains about checking a const string against NULL
#if defined(DDKBUILD)
#pragma warning(disable:4130)
#endif
#define REQUEST_TIMEOUT 5000
// UpdateDriverForPlugAndPlayDevices.InstallFlags constants
#define INSTALLFLAG_FORCE 0x00000001
#define INSTALLFLAG_READONLY 0x00000002
#define INSTALLFLAG_NONINTERACTIVE 0x00000004
#define INSTALLFLAG_BITS 0x00000007
/*
* Cfgmgr32.dll interface
*/
typedef CHAR *DEVNODEID_A, *DEVINSTID_A;
typedef WCHAR *DEVNODEID_W, *DEVINSTID_W;
#ifdef UNICODE
typedef DEVNODEID_W DEVNODEID;
typedef DEVINSTID_W DEVINSTID;
#else
typedef DEVNODEID_A DEVNODEID;
typedef DEVINSTID_A DEVINSTID;
#endif
DLL_DECLARE(WINAPI, CONFIGRET, CM_Locate_DevNode, (PDEVINST, DEVINSTID, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Reenumerate_DevNode, (DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_DevNode_Status, (PULONG, PULONG, DEVINST, ULONG));
DLL_DECLARE(WINAPI, int, __wgetmainargs, (int*, wchar_t***, wchar_t***, int, int*));
/*
* Globals
*/
HANDLE pipe_handle = INVALID_HANDLE_VALUE;
HANDLE syslog_ready_event = INVALID_HANDLE_VALUE;
HANDLE syslog_terminate_event = INVALID_HANDLE_VALUE;
PSID user_psid = NULL;
// Setup the Cfgmgr32 DLLs
static int init_dlls(void)
{
DLL_LOAD(Cfgmgr32.dll, CM_Locate_DevNode, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Reenumerate_DevNode, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_DevNode_Status, TRUE);
DLL_LOAD(Msvcrt.dll, __wgetmainargs, FALSE);
return 0;
}
// Log data with parent app through the pipe
void plog_v(const char *format, va_list args)
{
char buffer[STR_BUFFER_SIZE];
DWORD junk;
int size;
if (pipe_handle == INVALID_HANDLE_VALUE)
return;
buffer[0] = IC_PRINT_MESSAGE;
size = safe_vsnprintf(buffer+1, STR_BUFFER_SIZE-1, format, args);
if (size < 0) {
buffer[STR_BUFFER_SIZE-1] = 0;
size = STR_BUFFER_SIZE-2;
}
WriteFile(pipe_handle, buffer, (DWORD)size+2, &junk, NULL);
}
void plog(const char *format, ...)
{
va_list args;
va_start (args, format);
plog_v(format, args);
va_end (args);
}
// Notify the parent app
void send_status(char status)
{
DWORD junk;
WriteFile(pipe_handle, &status, 1, &junk, NULL);
}
// Post a WDI status code
void pstat(int status)
{
char data[2];
DWORD junk;
data[0] = IC_SET_STATUS;
data[1] = (char)status;
WriteFile(pipe_handle, data, 2, &junk, NULL);
}
// Query the parent app for data
int request_data(char req, void *buffer, int size)
{
OVERLAPPED overlapped;
DWORD rd_count;
DWORD r, count = (DWORD)size;
if ((buffer == NULL) || (size <= 0)) {
return -1;
}
// Set the overlapped for messaging
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (overlapped.hEvent == NULL) {
plog("failed to create overlapped");
return -1;
}
if (ReadFile(pipe_handle, buffer, count, &rd_count, &overlapped)) {
// Message was read synchronously
plog("received unexpected data");
CloseHandle(overlapped.hEvent);
return -1;
}
if (GetLastError() != ERROR_IO_PENDING) {
plog("failure to initiate read (%d)", (int)GetLastError());
CloseHandle(overlapped.hEvent);
return -1;
}
// Now that we're set to receive data, let's send our request
WriteFile(pipe_handle, &req, 1, &r, NULL);
// Wait for the response
r = WaitForSingleObject(overlapped.hEvent, REQUEST_TIMEOUT);
if ( (r == WAIT_OBJECT_0) && (GetOverlappedResult(pipe_handle, &overlapped, &rd_count, FALSE)) ) {
CloseHandle(overlapped.hEvent);
return (int)rd_count;
}
if (r == WAIT_TIMEOUT) {
plog("message request: timed out");
} else {
plog("read error: %d", (int)GetLastError());
}
CloseHandle(overlapped.hEvent);
return -1;
}
// Query parent app for device ID
char* req_id(enum installer_code id_code)
{
int size;
char* id_text[3] = {"device_id", "hardware_id", "user_sid"};
static char device_id[MAX_PATH_LENGTH];
static char hardware_id[MAX_PATH_LENGTH];
static char user_sid[MAX_PATH_LENGTH];
char* id = NULL;
switch(id_code) {
case IC_GET_DEVICE_ID:
id = device_id;
break;
case IC_GET_HARDWARE_ID:
id = hardware_id;
break;
case IC_GET_USER_SID:
id = user_sid;
break;
default:
plog("req_id: unknown ID requested");
return NULL;
}
memset(id, 0, MAX_PATH_LENGTH);
size = request_data(id_code, (void*)id, MAX_PATH_LENGTH);
if (size > 0) {
plog("got %s: %s", id_text[id_code-IC_GET_DEVICE_ID], id);
return id;
}
plog("failed to read %s", id_text[id_code-IC_GET_DEVICE_ID]);
return NULL;
}
/*
* Flag phantom/removed devices for reinstallation. See:
* http://msdn.microsoft.com/en-us/library/aa906206.aspx
*/
void check_removed(char* device_hardware_id)
{
unsigned i, removed = 0;
DWORD size, reg_type, config_flags;
ULONG status, pbm_number;
HDEVINFO dev_info;
SP_DEVINFO_DATA dev_info_data;
char hardware_id[STR_BUFFER_SIZE];
// List all known USB devices (including non present ones)
dev_info = SetupDiGetClassDevsA(NULL, "USB", NULL, DIGCF_ALLCLASSES);
if (dev_info == INVALID_HANDLE_VALUE) {
return;
}
// Find the ones that are driverless
for (i = 0; ; i++)
{
dev_info_data.cbSize = sizeof(dev_info_data);
if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) {
break;
}
// Find the hardware ID
if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID,
&reg_type, (BYTE*)hardware_id, STR_BUFFER_SIZE, &size)) {
continue;
}
// Match?
if (safe_strncmp(hardware_id, device_hardware_id, STR_BUFFER_SIZE) != 0) {
continue;
}
// Unplugged?
if (CM_Get_DevNode_Status(&status, &pbm_number, dev_info_data.DevInst, 0) != CR_NO_SUCH_DEVNODE) {
continue;
}
// Flag for reinstall on next plugin
if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_CONFIGFLAGS,
&reg_type, (BYTE*)&config_flags, sizeof(DWORD), &size)) {
plog("could not read SPDRP_CONFIGFLAGS for phantom device %s", hardware_id);
continue;
}
config_flags |= CONFIGFLAG_REINSTALL;
if (!SetupDiSetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_CONFIGFLAGS,
(BYTE*)&config_flags, sizeof(DWORD))) {
plog("could not write SPDRP_CONFIGFLAGS for phantom device %s", hardware_id);
continue;
}
removed++;
}
if (removed) {
plog("flagged %d removed devices for reinstallation", removed);
}
}
/*
* Converts a default system locate string to UTF-8
* (allocate returned string with 1 extra leading byte)
* Returns NULL on error
*/
static __inline char* xlocale_to_utf8(const char* str)
{
int size = 0;
wchar_t* wstr = NULL;
char* ustr = NULL;
// locale -> unicode
size = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
if (size <= 1)
return NULL;
if ((wstr = (wchar_t*)calloc(size, sizeof(wchar_t))) == NULL)
return NULL;
if (MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, size) != size) {
free(wstr);
return NULL;
}
// unicode -> UTF-8
size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
if (size <= 1) {
free(wstr);
return NULL;
}
// +1 for extra leading byte
if ((ustr = (char*)calloc(size+1, 1)) == NULL) {
free(wstr);
return NULL;
}
if (wchar_to_utf8_no_alloc(wstr, ustr+1, size) != size) {
free(ustr);
free(wstr);
return NULL;
}
free(wstr);
return ustr;
}
/*
* Send individual lines of the syslog section pointed by buffer back to the main application
* xbuffer's payload MUST start at byte 1 to accomodate the SYSLOG_MESSAGE prefix
*/
DWORD process_syslog(char* buffer, DWORD size)
{
DWORD i, write_size, junk, start = 0;
char* xbuffer;
char* ins_string = "<ins>";
char conversion_error[] = " ERROR: Unable to convert log entry to UTF-8";
if (buffer == NULL) return 0;
// CR/LF breakdown
for (i=0; i<size; i++) {
if ((buffer[i] == 0x0D) || (buffer[i] == 0x0A)) {
write_size = i-start + 1;
do {
buffer[i++] = 0;
} while ( ((buffer[i] == 0x0D) || (buffer[i] == 0x0A)) && (i <= size) );
// The setupapi.dev.log uses a dubious method to mark its current position
// If there's any "<ins>" line in any log file, it's game over then
if (safe_strcmp(ins_string, buffer + start) == 0) {
return start;
}
// The logs are using the system locale. Convert to UTF8 (with extra leading byte)
xbuffer = xlocale_to_utf8(&buffer[start]);
if (xbuffer == NULL) {
xbuffer = conversion_error;
}
// This is where we use the extra start byte
xbuffer[0] = IC_SYSLOG_MESSAGE;
WriteFile(pipe_handle, xbuffer, (DWORD)safe_strlen(&xbuffer[1])+2, &junk, NULL);
if (xbuffer != conversion_error) {
free(xbuffer);
}
start = i;
}
}
// start does not necessarily equate size, if there are truncated lines at the end
return start;
}
/*
* Read from the driver installation syslog in real-time
*/
void __cdecl syslog_reader_thread(void* param)
{
#define NB_SYSLOGS 3
char* syslog_name[NB_SYSLOGS] = { "\\inf\\setupapi.dev.log", "\\setupapi.log", "\\setupact.log" };
HANDLE log_handle;
DWORD last_offset, size, read_size, processed_size;
char *buffer = NULL;
char log_path[MAX_PATH_LENGTH];
DWORD duration = 0;
int i;
// Try the various driver installation logs
for (i=0; i<NB_SYSLOGS; i++) {
safe_strcpy(log_path, MAX_PATH_LENGTH, getenv("WINDIR")); // Use %WINDIR% env variable
safe_strcat(log_path, MAX_PATH_LENGTH, syslog_name[i]);
log_handle = CreateFileA(log_path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (log_handle != INVALID_HANDLE_VALUE) {
plog("using syslog '%s'", log_path);
break;
}
}
if (i == NB_SYSLOGS) {
plog("Could not open any syslog");
goto out;
}
// We assert that the log file is never gonna be bigger than 2 GB
// TODO: special case of setupapi.dev.log's last offset not being the end (v2)
last_offset = SetFilePointer(log_handle, 0, NULL, FILE_END);
if (last_offset == INVALID_SET_FILE_POINTER) {
plog("Could not set syslog offset");
goto out;
}
plog("sylog reader thread started");
SetEvent(syslog_ready_event);
processed_size = 0;
while(WaitForSingleObject(syslog_terminate_event, 0) != WAIT_OBJECT_0) {
// Find out if file size has increased since last time
size = GetFileSize(log_handle, NULL);
if (size == INVALID_FILE_SIZE) {
plog("could not read syslog file size");
goto out;
}
size -= last_offset;
if (size != 0) {
// Read from file and add a zero terminator
buffer = malloc(size+1);
if (buffer == NULL) {
plog("could not allocate buffer to read syslog");
goto out;
}
// Keep an extra spare byte at the beginning
if (!ReadFile(log_handle, buffer, size, &read_size, NULL)) {
plog("failed to read syslog");
goto out;
}
buffer[read_size] = 0;
// Send all the complete lines through the pipe
processed_size = process_syslog(buffer, read_size);
safe_free(buffer);
last_offset += processed_size;
// Reposition at start of last line if needed
if (processed_size != read_size) {
last_offset = SetFilePointer(log_handle, processed_size-read_size, NULL, FILE_CURRENT);
if (last_offset == INVALID_SET_FILE_POINTER) {
plog("Could not set syslog offset");
goto out;
}
}
// Reset adaptive sleep duration if we did send data out
if (processed_size !=0) {
duration = 0;
}
}
// Compute adaptive sleep duration
if (((size == 0) || (processed_size == 0)) && (duration < 500)) {
duration += 100; // read log more frequently on recent update
}
Sleep(duration);
}
out:
plog("syslog reader thread terminating");
safe_free(buffer);
CloseHandle(log_handle);
_endthread();
}
/*
* Convert various installation errors to their WDI counterpart
*/
static __inline int process_error(DWORD r, char* path) {
// Will fail if inf not signed, unless DRIVER_PACKAGE_LEGACY_MODE is specified.
// r = 87 ERROR_INVALID_PARAMETER on path == NULL or hardware_id empty string
// r = 2 ERROR_FILE_NOT_FOUND => failed to open inf
// r = 5 ERROR_ACCESS_DENIED if needs admin elevation
// r = 0xD ERROR_INVALID_DATA => inf is missing some data
// r = 0xE0000003 ERROR_GENERAL_SYNTAX the syntax of the inf is invalid or the inf is empty
// r = 0xE0000217 ERROR_BAD_SERVICE_INSTALLSECT happens if referencing a non present sys in svc section
// r = 0xE0000304 ERROR_INVALID_CATALOG_DATA => no cat
// r = 0xE000023F ERROR_NO_AUTHENTICODE_CATALOG => user cancelled on warnings
// r = 0xE0000235 ERROR_IN_WOW64 => trying to run a 32 bit installer on a 64 bit machine
// r = 0xE0000247 ERROR_DRIVER_STORE_ADD_FAILED if user decided not to install on warnings
// r = 0xE0000203 ERROR_NO_DRIVER_SELECTED if the driver provided is not compatible with the target platform
// r = 0x800B0100 ERROR_WRONG_INF_STYLE => missing cat entry in inf
// r = 0xE000022F ERROR_NO_CATALOG_FOR_OEM_INF => "reject unsigned driver" policy is enforced
// r = 0xB7 => missing DRIVER_PACKAGE_REPAIR flag
switch(r) {
case ERROR_NO_MORE_ITEMS:
plog("more recent driver was found (force option required)");
return WDI_ERROR_EXISTS;
case ERROR_NO_SUCH_DEVINST:
plog("device not detected (copying driver files for next time device is plugged in)");
return WDI_SUCCESS;
case ERROR_INVALID_PARAMETER:
plog("invalid path or hardware ID");
return WDI_ERROR_INVALID_PARAM;
case ERROR_FILE_NOT_FOUND:
plog("the system can not find the file specified");
return WDI_ERROR_NOT_FOUND;
case ERROR_ACCESS_DENIED:
plog("this process needs to be run with administrative privileges");
return WDI_ERROR_NEEDS_ADMIN;
case ERROR_IN_WOW64:
plog("attempted to use a 32 bit installer on a 64 bit machine");
return WDI_ERROR_WOW64;
case ERROR_INVALID_DATA:
case ERROR_WRONG_INF_STYLE:
case ERROR_GENERAL_SYNTAX:
plog("the syntax of the inf is invalid");
return WDI_ERROR_INF_SYNTAX;
case ERROR_BAD_SERVICE_INSTALLSECT:
plog("a section of the inf has a problem");
return WDI_ERROR_INF_SYNTAX;
case ERROR_INVALID_CATALOG_DATA:
plog("unable to locate cat file");
return WDI_ERROR_CAT_MISSING;
case ERROR_NO_AUTHENTICODE_CATALOG:
case ERROR_DRIVER_STORE_ADD_FAILED:
plog("operation cancelled by the user");
return WDI_ERROR_USER_CANCEL;
case ERROR_NO_DRIVER_SELECTED:
plog("the driver is not compatible with this version of Windows");
return WDI_ERROR_NOT_SUPPORTED;
case ERROR_ALREADY_EXISTS:
plog("driver already exists");
return WDI_ERROR_EXISTS;
case ERROR_NO_CATALOG_FOR_OEM_INF:
plog("your system policy has been modified from Windows defaults, and");
plog("is set to reject unsigned drivers. You must revert the driver");
plog("installation policy to default if you want to install this driver.");
plog("see http://articles.techrepublic.com.com/5100-10878_11-5875443.html");
return WDI_ERROR_UNSIGNED;
default:
plog("unhandled error %X", r);
return WDI_ERROR_OTHER;
}
}
// TODO: allow commandline options (v2)
// TODO: remove existing infs for similar devices (v2)
int __cdecl main(int argc_ansi, char** argv_ansi)
{
DWORD r;
BOOL b;
int i, ret, argc = argc_ansi, si=0;
char** argv = argv_ansi;
wchar_t **wenv, **wargv;
char* hardware_id = NULL;
char* device_id = NULL;
char* user_sid = NULL;
char* inf_name = NULL;
char path[MAX_PATH_LENGTH];
char destname[MAX_PATH_LENGTH];
uintptr_t syslog_reader_thid = -1L;
// Connect to the messaging pipe
pipe_handle = CreateFileA(INSTALLER_PIPE_NAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
if (pipe_handle == INVALID_HANDLE_VALUE) {
// If we can't connect to the pipe, someone is probably trying to run us standalone
printf("This application can not be run from the command line.\n");
printf("Please use your initial installer application if you want to install the driver.\n");
return WDI_ERROR_NOT_SUPPORTED;
}
if (init_dlls()) {
plog("could not init DLLs");
ret = WDI_ERROR_RESOURCE;
goto out;
}
// libwdi provides the arguments as UTF-16 => read them and convert to UTF-8
if (__wgetmainargs != NULL) {
__wgetmainargs(&argc, &wargv, &wenv, 1, &si);
argv = calloc(argc, sizeof(char*));
for (i=0; i<argc; i++) {
argv[i] = wchar_to_utf8(wargv[i]);
}
} else {
plog("unable to access UTF-16 args - trying ANSI");
}
if (argc < 2) {
printf("usage: %s <inf_name>\n", argv[0]);
plog("missing inf_name parameter");
}
inf_name = argv[1];
plog("got parameter %s", argv[1]);
r = GetFullPathNameU(".", MAX_PATH_LENGTH, path, NULL);
if ((r == 0) || (r > MAX_PATH_LENGTH)) {
plog("could not retrieve absolute path of working directory");
ret = WDI_ERROR_ACCESS;
goto out;
}
safe_strcat(path, MAX_PATH_LENGTH, "\\");
safe_strcat(path, MAX_PATH_LENGTH, inf_name);
device_id = req_id(IC_GET_DEVICE_ID);
hardware_id = req_id(IC_GET_HARDWARE_ID);
// Will be used if we ever need to create a file, as the original user, from this app
user_sid = req_id(IC_GET_USER_SID);
ConvertStringSidToSidA(user_sid, &user_psid);
// Setup the syslog reader thread
syslog_ready_event = CreateEvent(NULL, TRUE, FALSE, NULL);
syslog_terminate_event = CreateEvent(NULL, TRUE, FALSE, NULL);
syslog_reader_thid = _beginthread(syslog_reader_thread, 0, 0);
if ( (syslog_reader_thid == -1L)
|| (WaitForSingleObject(syslog_ready_event, 2000) != WAIT_OBJECT_0) ) {
plog("Unable to create syslog reader thread");
SetEvent(syslog_terminate_event);
// NB: if you try to close the syslog reader thread handle, you get a
// "more recent driver was found" error from UpdateForPnP. Weird...
}
// Find if the device is plugged in
send_status(IC_SET_TIMEOUT_INFINITE);
if ((hardware_id != NULL) && (hardware_id[0] != 0)) {
plog("Installing driver for %s - please wait...", hardware_id);
b = UpdateDriverForPlugAndPlayDevicesU(NULL, hardware_id, path, INSTALLFLAG_FORCE, NULL);
send_status(IC_SET_TIMEOUT_DEFAULT);
if (b == true) {
// Success
plog("driver update completed");
ret = WDI_SUCCESS;
goto out;
}
ret = process_error(GetLastError(), path);
if (ret != WDI_SUCCESS) {
goto out;
}
}
// TODO: try URL for OEMSourceMediaLocation (v2)
plog("Copying inf file (for the next time device is plugged) - please wait...");
send_status(IC_SET_TIMEOUT_INFINITE);
b = SetupCopyOEMInfU(path, NULL, SPOST_PATH, 0, destname, MAX_PATH_LENGTH, NULL, NULL);
send_status(IC_SET_TIMEOUT_DEFAULT);
if (b) {
plog("copied inf to %s", destname);
ret = WDI_SUCCESS;
goto out;
}
ret = process_error(GetLastError(), path);
if (ret != WDI_SUCCESS) {
goto out;
}
// If needed, flag removed devices for reinstallation. see:
// http://msdn.microsoft.com/en-us/library/aa906206.aspx
check_removed(hardware_id);
out:
// Report any error status code and wait for target app to read it
send_status(IC_INSTALLER_COMPLETED);
pstat(ret);
// TODO: have libwi send an ACK?
Sleep(1000);
SetEvent(syslog_terminate_event);
if (argv != argv_ansi) {
for (i=0; i<argc; i++) {
safe_free(argv[i]);
}
safe_free(argv);
}
CloseHandle(syslog_ready_event);
CloseHandle(syslog_terminate_event);
CloseHandle((HANDLE)syslog_reader_thid);
CloseHandle(pipe_handle);
return ret;
}
@@ -0,0 +1,168 @@
/*
* Library for WinUSB/libusb automated driver installation
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <windows.h>
#if !defined(bool)
#define bool BOOL
#endif
#if !defined(true)
#define true TRUE
#endif
#if !defined(false)
#define false FALSE
#endif
#define MAX_DESC_LENGTH 128
#define MAX_PATH_LENGTH 128
#define MAX_KEY_LENGTH 256
#define STR_BUFFER_SIZE 256
#define MAX_GUID_STRING_LENGTH 40
#define INSTALLER_PIPE_NAME "\\\\.\\pipe\\libwdi-installer"
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
#define static_strcpy(dst, src) safe_strcpy(dst, sizeof(dst), src)
#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
#define static_strcat(dst, src) safe_strcat(dst, sizeof(dst), src)
#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_sprintf _snprintf
#define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str))
#define static_sprintf(dest, format, ...) safe_sprintf(dest, sizeof(dest), format, __VA_ARGS__)
#define safe_swprintf _snwprintf
#define safe_strdup _strdup
#if defined(_MSC_VER)
#define safe_vsnprintf(buf, size, format, arg) _vsnprintf_s(buf, size, _TRUNCATE, format, arg)
#else
#define safe_vsnprintf vsnprintf
#endif
/*
* For communications between installer <-> libwdi
*/
enum installer_code {
IC_PRINT_MESSAGE,
IC_SYSLOG_MESSAGE,
IC_GET_DEVICE_ID,
IC_GET_HARDWARE_ID,
IC_GET_USER_SID,
IC_SET_TIMEOUT_INFINITE,
IC_SET_TIMEOUT_DEFAULT,
IC_SET_STATUS,
IC_INSTALLER_COMPLETED,
};
/*
* Windows versions
*/
enum windows_version {
WINDOWS_UNDEFINED,
WINDOWS_UNSUPPORTED,
WINDOWS_2K,
WINDOWS_XP,
WINDOWS_2003_XP64,
WINDOWS_VISTA,
WINDOWS_7
};
/*
* API macros - from libusb-win32 1.x
*/
#define DLL_DECLARE(api, ret, name, args) \
typedef ret (api * __dll_##name##_t)args; __dll_##name##_t name = NULL
#define DLL_LOAD(dll, name, ret_on_failure) \
do { \
HMODULE h = GetModuleHandle(#dll); \
if (!h) \
h = LoadLibrary(#dll); \
if (!h) { \
if (ret_on_failure) { return -1; } \
else { break; } \
} \
name = (__dll_##name##_t)GetProcAddress(h, #name); \
if (name) break; \
name = (__dll_##name##_t)GetProcAddress(h, #name "A"); \
if (name) break; \
name = (__dll_##name##_t)GetProcAddress(h, #name "W"); \
if (name) break; \
if(ret_on_failure) \
return WDI_ERROR_NOT_SUPPORTED; \
} while(0)
/*
* Cfgmgr32.dll interface
*/
typedef DWORD DEVNODE, DEVINST;
typedef DEVNODE *PDEVNODE, *PDEVINST;
typedef DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
#define CR_SUCCESS 0x00000000
#define CR_NO_SUCH_DEVNODE 0x0000000D
#define CONFIGFLAG_REINSTALL 0x00000020
#define CM_REENUMERATE_NORMAL 0x00000000
#define CM_REENUMERATE_SYNCHRONOUS 0x00000001
#define CM_REENUMERATE_RETRY_INSTALLATION 0x00000002
#define CM_REENUMERATE_ASYNCHRONOUS 0x00000004
#define CM_REENUMERATE_BITS 0x00000007
/*
* DifXApi.dll interface
*/
#define DRIVER_PACKAGE_REPAIR 0x00000001
#define DRIVER_PACKAGE_FORCE 0x00000004
#define DRIVER_PACKAGE_LEGACY_MODE 0x00000010
#define ERROR_INVALID_CATALOG_DATA 0xE0000304
#ifndef ERROR_DRIVER_STORE_ADD_FAILED
#define ERROR_DRIVER_STORE_ADD_FAILED 0xE0000247
#endif
#ifndef ERROR_NO_AUTHENTICODE_CATALOG
#define ERROR_NO_AUTHENTICODE_CATALOG 0xE000023F
#endif
#ifndef ERROR_IN_WOW64
#define ERROR_IN_WOW64 0xE0000235
#endif
typedef enum {
DIFXAPI_SUCCESS,
DIFXAPI_INFO,
DIFXAPI_WARNING,
DIFXAPI_ERROR
} DIFXAPI_LOG;
typedef void (__cdecl* DIFXAPILOGCALLBACK)(DIFXAPI_LOG EventType, DWORD Error, LPCSTR EventDescription, PVOID CallbackContext);
typedef struct {
LPCSTR pApplicationId;
LPCSTR pDisplayName;
LPCSTR pProductName;
LPCSTR pMfgName;
} INSTALLERINFO, *PINSTALLERINFO;
typedef const PINSTALLERINFO PCINSTALLERINFO;
@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="installer_x64"
ProjectGUID="{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}"
RootNamespace="installerx64"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper\installer_x64"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS; _WIN64"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="newdev.lib setupapi.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper\installer_x64"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS; _WIN64"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="newdev.lib setupapi.lib"
LinkIncremental="1"
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="installer.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="installer.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>installer_x64</ProjectName>
<ProjectGuid>{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}</ProjectGuid>
<RootNamespace>installerx64</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\helper\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\helper\installer_x64\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\helper\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\helper\installer_x64\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS; _WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>newdev.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS; _WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>newdev.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="installer.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="installer.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="installer.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="installer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
@@ -0,0 +1,23 @@
TARGETNAME=installer_x64
TARGETTYPE=PROGRAM
_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
!IFNDEF MSC_WARNING_LEVEL
MSC_WARNING_LEVEL=/W3
!ENDIF
USE_MSVCRT=1
UMTYPE=console
UMBASE=0x01000000
INCLUDES=..\msvc;$(DDK_INC_PATH)
C_DEFINES = $(C_DEFINES) /DDDKBUILD
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\newdev.lib \
$(SDK_LIB_PATH)\setupapi.lib
SOURCES=installer.c
@@ -0,0 +1,195 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="installer_x86"
ProjectGUID="{9B1C561E-F95B-4849-A7AA-A4350E227C20}"
RootNamespace="installerx86"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper\installer_x86"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="newdev.lib setupapi.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\helper\installer_x86"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="newdev.lib setupapi.lib"
LinkIncremental="1"
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="installer.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="installer.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>installer_x86</ProjectName>
<ProjectGuid>{9B1C561E-F95B-4849-A7AA-A4350E227C20}</ProjectGuid>
<RootNamespace>installerx86</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\installer_x86\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\helper\installer_x86\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>newdev.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>newdev.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="installer.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="installer.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="installer.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="installer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
@@ -0,0 +1,23 @@
TARGETNAME=installer_x86
TARGETTYPE=PROGRAM
_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
!IFNDEF MSC_WARNING_LEVEL
MSC_WARNING_LEVEL=/W3
!ENDIF
USE_MSVCRT=1
UMTYPE=console
UMBASE=0x01000000
INCLUDES=..\msvc;$(DDK_INC_PATH)
C_DEFINES = $(C_DEFINES) /DDDKBUILD
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\newdev.lib \
$(SDK_LIB_PATH)\setupapi.lib
SOURCES=installer.c
@@ -0,0 +1,144 @@
; #INF_FILENAME#
; Copyright (c) 2010 libusb-win32 (GNU LGPL)
[Strings]
DeviceName = "#DEVICE_DESCRIPTION#"
VendorName = "#DEVICE_MANUFACTURER#"
SourceName = "#DEVICE_DESCRIPTION# Install Disk"
DeviceID = "#DEVICE_HARDWARE_ID#"
DeviceGUID = "#DEVICE_INTERFACE_GUID#"
[Version]
Signature = "$Windows NT$"
Class = "libusb-win32 devices"
ClassGuid = {EB781AAF-9C70-4523-A5DF-642A87ECA567}
Provider = "libusb-win32"
CatalogFile = #CAT_FILENAME#
DriverVer = #DRIVER_DATE#, #DRIVER_VERSION#
[ClassInstall32]
Addreg = libusb_class_install_add_reg
[libusb_class_install_add_reg]
HKR,,,0,"libusb-win32 devices"
HKR,,Icon,,-20
[Manufacturer]
%VendorName% = Devices, NT, NTAMD64, NTIA64
;--------------------------------------------------------------------------
; libusb-win32 files
;--------------------------------------------------------------------------
[SourceDisksNames]
1 = %SourceName%
[SourceDisksFiles.x86]
libusb0.sys = 1,x86
libusb0_x86.dll = 1,x86
[SourceDisksFiles.amd64]
libusb0.sys = 1,amd64
libusb0.dll = 1,amd64
libusb0_x86.dll = 1,x86
[SourceDisksFiles.ia64]
libusb0.sys = 1,ia64
libusb0.dll = 1,ia64
libusb0_x86.dll = 1,x86
[DestinationDirs]
libusb_files_sys = 10,system32\drivers
libusb_files_dll = 10,system32
libusb_files_dll_wow64 = 10,syswow64
libusb_files_dll_x86 = 10,system32
[libusb_files_sys]
libusb0.sys
[libusb_files_dll]
libusb0.dll
[libusb_files_dll_x86]
libusb0.dll, libusb0_x86.dll
[libusb_files_dll_wow64]
libusb0.dll, libusb0_x86.dll
;--------------------------------------------------------------------------
; libusb-win32 device driver
;--------------------------------------------------------------------------
[LIBUSB_WIN32_DEV.NT]
CopyFiles = libusb_files_sys, libusb_files_dll_x86
[LIBUSB_WIN32_DEV.NTAMD64]
CopyFiles = libusb_files_sys, libusb_files_dll, libusb_files_dll_wow64
[LIBUSB_WIN32_DEV.NTIA64]
CopyFiles = libusb_files_sys, libusb_files_dll, libusb_files_dll_wow64
[LIBUSB_WIN32_DEV.NT.HW]
DelReg = libusb_del_reg_hw
AddReg = libusb_add_reg_hw
[LIBUSB_WIN32_DEV.NTAMD64.HW]
DelReg = libusb_del_reg_hw
AddReg = libusb_add_reg_hw
[LIBUSB_WIN32_DEV.NTIA64.HW]
DelReg = libusb_del_reg_hw
AddReg = libusb_add_reg_hw
[LIBUSB_WIN32_DEV.NT.Services]
AddService = libusb0, 0x00000002, libusb_add_service
[LIBUSB_WIN32_DEV.NTAMD64.Services]
AddService = libusb0, 0x00000002, libusb_add_service
[LIBUSB_WIN32_DEV.NTIA64.Services]
AddService = libusb0, 0x00000002, libusb_add_service
; Older versions of this .inf file installed filter drivers. They are not
; needed any more and must be removed
[libusb_del_reg_hw]
HKR,,LowerFilters
HKR,,UpperFilters
; libusb-win32 device properties
[libusb_add_reg_hw]
HKR,,SurpriseRemovalOK,0x00010001,1
; (Optional) the usb configuration value to select when this device
; is started. If this key does not exist the first config is selected.
;HKR,,InitialConfigValue,0x00010001,<your config value>
;--------------------------------------------------------------------------
; libusb-win32 service
;--------------------------------------------------------------------------
[libusb_add_service]
DisplayName = "libusb-win32 - Kernel Driver #DRIVER_DATE# #DRIVER_VERSION#"
ServiceType = 1
StartType = 3
ErrorControl = 0
ServiceBinary = %12%\libusb0.sys
;--------------------------------------------------------------------------
; libusb-win32 devices
;--------------------------------------------------------------------------
; Hardware IDs in a 'Devices' section can be installed by libusb-win32
; using usb_install_driver_np(), usb_install_driver_np_rundll(), or the
; inf-wizard utility.
;
[Devices]
%DeviceName% = LIBUSB_WIN32_DEV, USB\%DeviceID%
[Devices.NT]
%DeviceName% = LIBUSB_WIN32_DEV.NT, USB\%DeviceID%
[Devices.NTAMD64]
%DeviceName% = LIBUSB_WIN32_DEV.NTAMD64, USB\%DeviceID%
[Devices.NTIA64]
%DeviceName% = LIBUSB_WIN32_DEV.NTIA64, USB\%DeviceID%
@@ -0,0 +1,257 @@
/*
* Library for WinUSB/libusb automated driver installation
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
* Parts of the code from libusb by Daniel Drake, Johannes Erdfelt et al.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <windows.h>
#if !defined(bool)
#define bool BOOL
#endif
#if !defined(true)
#define true TRUE
#endif
#if !defined(false)
#define false FALSE
#endif
#if defined(DLL_EXPORT)
#define LIBWDI_EXP __declspec(dllexport)
#else
#define LIBWDI_EXP
#endif
/*
* Set the default calling convention to WINAPI (__stdcall)
*/
#if !defined(LIBWDI_API)
#define LIBWDI_API WINAPI
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Type of driver to install
*/
enum wdi_driver_type {
WDI_WINUSB,
WDI_LIBUSB,
WDI_USER,
WDI_NB_DRIVERS // Total number of drivers in the enum
};
/*
* Log level
*/
enum wdi_log_level {
WDI_LOG_LEVEL_DEBUG,
WDI_LOG_LEVEL_INFO,
WDI_LOG_LEVEL_WARNING,
WDI_LOG_LEVEL_ERROR
};
/*
* Error codes. Most libwdi functions return 0 on success or one of these
* codes on failure.
* You can use wdi_strerror() to retrieve a short string description of
* a wdi_error enumeration value.
*/
enum wdi_error {
/** Success (no error) */
WDI_SUCCESS = 0,
/** Input/output error */
WDI_ERROR_IO = -1,
/** Invalid parameter */
WDI_ERROR_INVALID_PARAM = -2,
/** Access denied (insufficient permissions) */
WDI_ERROR_ACCESS = -3,
/** No such device (it may have been disconnected) */
WDI_ERROR_NO_DEVICE = -4,
/** Entity not found */
WDI_ERROR_NOT_FOUND = -5,
/** Resource busy, or API call already running */
WDI_ERROR_BUSY = -6,
/** Operation timed out */
WDI_ERROR_TIMEOUT = -7,
/** Overflow */
WDI_ERROR_OVERFLOW = -8,
/** Another installation is pending */
WDI_ERROR_PENDING_INSTALLATION = -9,
/** System call interrupted (perhaps due to signal) */
WDI_ERROR_INTERRUPTED = -10,
/** Could not acquire resource (Insufficient memory, etc) */
WDI_ERROR_RESOURCE = -11,
/** Operation not supported or unimplemented on this platform */
WDI_ERROR_NOT_SUPPORTED = -12,
/** Entity already exists */
WDI_ERROR_EXISTS = -13,
/** Cancelled by user */
WDI_ERROR_USER_CANCEL = -14,
/** Couldn't run installer with required privileges */
WDI_ERROR_NEEDS_ADMIN = -15,
/** Attempted to run the 32 bit installer on 64 bit */
WDI_ERROR_WOW64 = -16,
/** Bad inf syntax */
WDI_ERROR_INF_SYNTAX = -17,
/** Missing cat file */
WDI_ERROR_CAT_MISSING = -18,
/** System policy prevents the installation of unsigned drivers */
WDI_ERROR_UNSIGNED = -19,
/** Other error */
WDI_ERROR_OTHER = -99
/** IMPORTANT: when adding new values to this enum, remember to
update the wdi_strerror() function implementation! */
};
/*
* Device information structure, used by libwdi functions
*/
struct wdi_device_info {
/** (Optional) Pointer to the next element in the chained list. NULL if unused */
struct wdi_device_info *next;
/** USB VID */
unsigned short vid;
/** USB PID */
unsigned short pid;
/** Whether the USB device is composite */
bool is_composite;
/** (Optional) Composite USB interface number */
unsigned char mi;
/** USB Device description, usually provided by the device irself */
char* desc;
/** Windows' driver (service) name */
char* driver;
/** (Optional) Microsoft's device URI string. NULL if unused */
char* device_id;
/** (Optional) Microsoft's hardware ID string. NULL if unused */
char* hardware_id;
};
/*
* Optional settings, used by libwdi functions
*/
// wdi_create_list options
struct wdi_options_create_list {
/** list all devices, instead of just the ones that are driverless */
bool list_all;
/** also list generic hubs and composite parent devices */
bool list_hubs;
/** trim trailing whitespaces from the description string */
bool trim_whitespaces;
};
// wdi_prepare_driver options:
struct wdi_options_prepare_driver {
/** type of driver to use. Should be either WDI_WINUSB, WDI_LIBUSB or WDI_USER */
int driver_type;
/** Vendor name that should be used for the Manufacturer in the inf */
char* vendor_name;
};
// wdi_install_driver options:
struct wdi_options_install_driver {
/** Handle to a Window application that should receive a modal progress dialog */
HWND hWnd;
};
/*
* Convert a libwdi error to a human readable error message
*/
LIBWDI_EXP const char* LIBWDI_API wdi_strerror(int errcode);
/*
* Check if a specific driver is supported (embedded) in the current version of libwdi
*/
LIBWDI_EXP bool LIBWDI_API wdi_is_driver_supported(int driver_type, VS_FIXEDFILEINFO* driver_info);
/*
* Retrieve the full Vendor name from a Vendor ID (VID)
*/
LIBWDI_EXP const char* LIBWDI_API wdi_get_vendor_name(unsigned short vid);
/*
* Return a wdi_device_info list of USB devices
* parameter: driverless_only - boolean
*/
LIBWDI_EXP int LIBWDI_API wdi_create_list(struct wdi_device_info** list,
struct wdi_options_create_list* options);
/*
* Release a wdi_device_info list allocated by the previous call
*/
LIBWDI_EXP int LIBWDI_API wdi_destroy_list(struct wdi_device_info* list);
/*
* Create an inf file for a specific device
*/
LIBWDI_EXP int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, char* path,
char* inf_name, struct wdi_options_prepare_driver* options);
/*
* Install a driver for a specific device
*/
LIBWDI_EXP int LIBWDI_API wdi_install_driver(struct wdi_device_info* device_info, char* path,
char* inf_name, struct wdi_options_install_driver* options);
/*
* Set the log verbosity
*/
LIBWDI_EXP int LIBWDI_API wdi_set_log_level(int level);
/*
* Set the Windows callback message for log notification
*/
LIBWDI_EXP int LIBWDI_API wdi_register_logger(HWND hWnd, UINT message, DWORD buffsize);
/*
* Unset the Windows callback message for log notification
*/
LIBWDI_EXP int LIBWDI_API wdi_unregister_logger(HWND hWnd);
/*
* Read a log message after a log notification
*/
LIBWDI_EXP int LIBWDI_API wdi_read_logger(char* buffer, DWORD buffer_size, DWORD* message_size);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,92 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winresrc.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Neutral) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winresrc.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,1,117
PRODUCTVERSION 1,0,1,117
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000904b0"
BEGIN
VALUE "Comments", "http://libusb.org/wiki/libwdi"
VALUE "CompanyName", "libusb.org"
VALUE "FileDescription", "libwdi"
VALUE "FileVersion", "1, 0, 1, 117"
VALUE "InternalName", "libwdi"
VALUE "LegalCopyright", "See individual source files, GNU LGPL v2.1 or later."
VALUE "LegalTrademarks", "http://www.gnu.org/licenses/lgpl-2.1.html"
VALUE "OriginalFilename", "libwdi"
VALUE "ProductName", "libwdi"
VALUE "ProductVersion", "1, 0, 1, 117"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x9, 1200
END
END
#endif // English (Neutral) resources
/////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,395 @@
/*
* Library for USB automated driver installation
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
* Parts of the code from libusb by Daniel Drake, Johannes Erdfelt et al.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <stdio.h>
#include <shlobj.h>
#include <process.h>
#include <stdint.h>
#include <wingdi.h>
#include <config.h>
#include "installer.h"
#include "libwdi.h"
#include "logging.h"
#include "resource.h"
// WM_APP is not sent on focus, unlike WM_USER
enum stdlg_user_message_type {
UM_PROGRESS_START = WM_APP,
UM_PROGRESS_STOP,
};
// Messages that appear in our progress bar as time passes
const char* progress_message[] = {
"Installation can take some time...",
"The installation process can take up to 5 minutes...",
"The reason it can be so long...",
"...is because a System Restore point is created.", // 1 min
"If it's the first time a restore point is created...",
"...an extended delay is to expected.",
"Microsoft offers no means of checking progress...",
"...so we can't say how long it'll take...", // 2 mins
"Please continue to be patient...",
"There's a 5 minutes timeout enventually...",
"...so if there's a problem, the process will abort.",
"I've really seen an installation take 5 minutes...", // 3 mins
"...on a Vista 64 machine with a very large disk.",
"So how was your day...",
"...before it got ruined by this endless installation?",
"Seriously, what is taking this process so long?!", // 4 mins
"Aborting in 45 seconds...",
"Aborting in 30 seconds...",
"Aborting in 15 seconds...",
};
#ifndef PBS_MARQUEE
#define PBS_MARQUEE 0x08
#endif
#ifndef PBM_SETMARQUEE
#define PBM_SETMARQUEE (WM_USER+10)
#endif
/*
* Globals
*/
static uintptr_t progress_thid = -1L;
static HWND hProgress = INVALID_HANDLE_VALUE;
static HWND hProgressBar = INVALID_HANDLE_VALUE;
static HWND hProgressText = INVALID_HANDLE_VALUE;
static HINSTANCE app_instance = NULL;
static int (*progress_function)(void*);
static void* progress_arglist;
static HANDLE progress_mutex = INVALID_HANDLE_VALUE;
// Work around for CreateFont on DDK (would require end user apps linking with Gdi32 othwerwise)
static HFONT (WINAPI *pCreateFontA)(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCSTR) = NULL;
#define INIT_CREATEFONT if (pCreateFontA== NULL) { \
pCreateFontA = (HFONT (WINAPI *)(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCSTR)) \
GetProcAddress(GetModuleHandleA("Gdi32"), "CreateFontA"); \
}
#define IS_CREATEFONT_AVAILABLE (pCreateFontA != NULL)
extern char *windows_error_str(uint32_t retval);
/*
* Detect if a Windows Security prompt is active, by enumerating the
* whole Windows tree and looking for a security popup
*/
BOOL CALLBACK security_prompt_callback(HWND hWnd, LPARAM lParam)
{
char str_buf[STR_BUFFER_SIZE];
HWND *hFound = (HWND*)lParam;
const char* security_string = "Windows Security";
// The security prompt has the popup window style
if (GetWindowLong(hWnd, GWL_STYLE) & WS_POPUPWINDOW) {
str_buf[0] = 0;
GetWindowTextA(hWnd, str_buf, STR_BUFFER_SIZE);
str_buf[STR_BUFFER_SIZE-1] = 0;
if (safe_strcmp(str_buf, security_string) == 0) {
*hFound = hWnd;
}
}
return TRUE;
}
HWND find_security_prompt(void) {
HWND hSecurityPrompt = NULL;
EnumChildWindows(GetDesktopWindow(), security_prompt_callback, (LPARAM)&hSecurityPrompt);
return hSecurityPrompt;
}
/*
* Thread executed by the run_with_progress_bar() function
*/
void __cdecl progress_thread(void* param)
{
int r;
// Call the user provided function
r = (*progress_function)(progress_arglist);
progress_thid = -1L;
PostMessage(hProgress, UM_PROGRESS_STOP, (WPARAM)r, 0);
_endthread();
}
/*
* Center a dialog with regards to the main application Window
*/
static void center_dialog(HWND dialog)
{
HWND hParent;
POINT Point;
RECT DialogRect;
RECT ParentRect;
int nWidth;
int nHeight;
hParent = GetParent(dialog);
if (hParent == NULL) return;
// Get the size of the dialog box.
GetWindowRect(dialog, &DialogRect);
GetClientRect(hParent, &ParentRect);
// Calculate the height and width of the current dialog
nWidth = DialogRect.right - DialogRect.left;
nHeight = DialogRect.bottom - DialogRect.top;
// Find the center point and convert to screen coordinates.
Point.x = (ParentRect.right - ParentRect.left) / 2;
Point.y = (ParentRect.bottom - ParentRect.top) / 2;
ClientToScreen(hParent, &Point);
// Calculate the new x, y starting point.
Point.x -= nWidth / 2;
Point.y -= nHeight / 2 + 35;
// Move the window.
MoveWindow(dialog, Point.x, Point.y, nWidth, nHeight, FALSE);
}
/*
* Dialog sub-elements
*/
static void init_children(HWND hDlg) {
HFONT hFont;
// Progress Bar
hProgressBar = CreateWindowExA(WS_EX_NOPARENTNOTIFY, PROGRESS_CLASS,
NULL,
WS_CHILDWINDOW | WS_VISIBLE | PBS_MARQUEE,
10,35,250,12,
hDlg,
NULL,
app_instance,
NULL);
if (hProgressBar == NULL) {
wdi_err("Unable to create progress bar: %s", windows_error_str(0));
}
// Start progress animation
PostMessage(hProgressBar, PBM_SETMARQUEE, TRUE, 0);
// Progress Text
hProgressText = CreateWindowExA(WS_EX_NOPARENTNOTIFY, WC_STATIC,
"Installing Driver...",
WS_CHILDWINDOW | WS_VISIBLE | WS_GROUP,
12,12,250,16,
hDlg,
NULL,
app_instance,
NULL);
if (hProgressBar == NULL) {
wdi_err("Unable to create progress text: %s", windows_error_str(0));
}
// Set the font to MS Dialog default
INIT_CREATEFONT;
if (IS_CREATEFONT_AVAILABLE) {
hFont = pCreateFontA(-11, 0, 0, 0, FW_DONTCARE, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH, "MS Shell Dlg 2");
SendMessage(hProgressText, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
}
}
/*
* Callback for the run_with_progress_bar() function
*/
LRESULT CALLBACK progress_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT loc;
HANDLE handle;
static int installation_time = 0; // active installation time, in secs
const int msg_max = sizeof(progress_message) / sizeof(progress_message[0]);
static int msg_index = 0;
int i;
// coordinates that we want to disable (=> no resize)
static LRESULT disabled[9] = { HTLEFT, HTRIGHT, HTTOP, HTBOTTOM, HTSIZE,
HTTOPLEFT, HTTOPRIGHT, HTBOTTOMLEFT, HTBOTTOMRIGHT };
switch (message) {
case WM_CREATE:
// Reset static variables
installation_time = 0;
msg_index = 0;
hProgress = hDlg;
// Start modal (disable parent Window)
EnableWindow(GetParent(hDlg), FALSE);
init_children(hProgress);
center_dialog(hProgress);
// Send a WM_TIMER message every second
SetTimer(hProgress, 1, 1000, NULL);
PostMessage(hProgress, UM_PROGRESS_START, 0, 0);
return (INT_PTR)TRUE;
case WM_NCHITTEST:
// Check coordinates to prevent resize actions
loc = DefWindowProc(hDlg, message, wParam, lParam);
for(i = 0; i < 9; i++) {
if (loc == disabled[i]) {
return (INT_PTR)TRUE;
}
}
return (INT_PTR)FALSE;
case UM_PROGRESS_START:
if (progress_thid != -1L) {
wdi_err("program assertion failed - another operation is in progress");
} else {
// Using a thread prevents application freezout on security warning
progress_thid = _beginthread(progress_thread, 0, NULL);
if (progress_thid != -1L) {
return (INT_PTR)TRUE;
}
wdi_err("unable to create progress_thread");
}
// Fall through and return an error
wParam = (WPARAM)WDI_ERROR_RESOURCE;
case UM_PROGRESS_STOP:
// If you don't re-enable the parent Window before leaving
// all kind of bad things happen (other Windows get activated, etc.)
EnableWindow(GetParent(hDlg), TRUE);
PostQuitMessage((int)wParam);
DestroyWindow(hProgress);
return (INT_PTR)TRUE;
case WM_TIMER:
if (find_security_prompt() == NULL) {
installation_time++; // Only increment outside of security prompts
if ( (msg_index < msg_max) && (installation_time > 15*(msg_index+1)) ) {
// Change the progress blurb
SetWindowTextA(hProgressText, progress_message[msg_index]);
msg_index++;
} else if ( (installation_time > 300) && (progress_thid != -1L) ) {
// Wait 300 (loose) seconds and kill the thread
// 300 secs is the timeout for driver installation on Vista
wdi_err("progress timeout expired - KILLING THREAD!");
handle = OpenThread(THREAD_TERMINATE, FALSE, (DWORD)progress_thid);
TerminateThread(handle, -1);
CloseHandle(handle);
PostQuitMessage(WDI_ERROR_TIMEOUT);
DestroyWindow(hProgress);
return (INT_PTR)FALSE;
}
}
return (INT_PTR)TRUE;
case WM_CLOSE: // prevent closure using Alt-F4
return (INT_PTR)TRUE;
case WM_DESTROY: // close application
hProgress = INVALID_HANDLE_VALUE;
return (INT_PTR)FALSE;
}
return DefWindowProc(hDlg, message, wParam, lParam);
}
/*
* Call a blocking function (returning an int) as a modal thread with a progress bar
*/
int run_with_progress_bar(HWND hWnd, int(*function)(void*), void* arglist) {
HWND hDlg;
MSG msg;
WNDCLASSEX wc;
BOOL r;
if ( (function == NULL) || (hWnd == NULL) ) {
return WDI_ERROR_INVALID_PARAM;
}
app_instance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
// protect access to the thread variables and prevent 2 progress
// dialogs from executing at the same time
progress_mutex = CreateMutex(NULL, TRUE, NULL);
if ((progress_mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) {
wdi_err("could not obtain progress dialog mutex - is another dialog active?");
progress_mutex = INVALID_HANDLE_VALUE;
return WDI_ERROR_BUSY;
}
progress_function = function;
progress_arglist = arglist;
// Since our lib can be static, we can't use resources
// => create the whole dialog manually.
// First we create Window class if it doesn't already exist
if (!GetClassInfoExA(app_instance, "wdi_progress_class", &wc)) {
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS | CS_SAVEBITS;
wc.lpfnWndProc = progress_callback;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = app_instance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "wdi_progress_class";
wc.lpszMenuName = NULL;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
if (!RegisterClassExA(&wc)) {
wdi_err("can't register class %s", windows_error_str(0));
safe_closehandle(progress_mutex);
return WDI_ERROR_RESOURCE;
}
}
// Then we create the dialog base
hDlg = CreateWindowExA(WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT,
"wdi_progress_class", "Installing driver...",
WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_THICKFRAME,
100, 100, 287, 102, hWnd, NULL, app_instance, NULL);
if (hDlg == NULL) {
wdi_err("Unable to create progress dialog: %s", windows_error_str(0));
safe_closehandle(progress_mutex);
return WDI_ERROR_RESOURCE;
}
// Finally we Display the dialog...
ShowWindow(hDlg, SW_SHOWNORMAL);
UpdateWindow(hDlg);
// ...and handle the message processing loop
while( (r = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (r == -1) {
wdi_err("GetMessage error");
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
safe_closehandle(progress_mutex);
return (int)msg.wParam;
}
@@ -0,0 +1,369 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="libwdi (dll)"
ProjectGUID="{79275348-41A4-4D07-8990-4068C9594A2C}"
RootNamespace="libwdi"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll\libwdi"
ConfigurationType="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Embedding binary resources"
CommandLine="$(TargetDir)\..\helper\embedder $(InputDir)\embedded.h"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="E:\WinDDK\7600.16385.0"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib newdev.lib"
OutputFile="$(OutDir)\libwdi.dll"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll\libwdi"
ConfigurationType="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Embedding binary resources"
CommandLine="$(TargetDir)\..\helper\embedder $(InputDir)\embedded.h"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT"
RuntimeLibrary="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="E:\WinDDK\7600.16385.0"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib newdev.lib"
OutputFile="$(OutDir)\libwdi.dll"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll\libwdi"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Embedding binary resources"
CommandLine="$(TargetDir)\..\helper\embedder $(InputDir)\embedded.h"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="E:\WinDDK\7600.16385.0"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib newdev.lib"
OutputFile="$(OutDir)\libwdi.dll"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\dll\libwdi"
ConfigurationType="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Embedding binary resources"
CommandLine="$(TargetDir)\..\helper\embedder $(InputDir)\embedded.h"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT"
RuntimeLibrary="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="E:\WinDDK\7600.16385.0"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib newdev.lib"
OutputFile="$(OutDir)\libwdi.dll"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\libwdi.c"
>
</File>
<File
RelativePath=".\logging.c"
>
</File>
<File
RelativePath=".\tokenizer.c"
>
</File>
<File
RelativePath=".\vid_data.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\msvc\config.h"
>
</File>
<File
RelativePath=".\installer.h"
>
</File>
<File
RelativePath=".\libwdi.h"
>
</File>
<File
RelativePath=".\logging.h"
>
</File>
<File
RelativePath=".\tokenizer.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
>
<File
RelativePath=".\libusb-win32.inf.in"
>
</File>
<File
RelativePath=".\libwdi.rc"
>
</File>
<File
RelativePath=".\winusb.inf.in"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,33 @@
#TARGETTYPE is not defined, to allow selection between static lib or DLL with ddk_build
TARGETNAME=libwdi
#Must be set, else DLL build will look for libwdi.def
DLLDEF=
#DLL_EXPORT must be provided as a macro when buidling a DLL
!IF "$(TARGETTYPE)"=="DYNLINK"
DLL_DEFINES=/DDLL_EXPORT
!ENDIF
!IFNDEF MSC_WARNING_LEVEL
MSC_WARNING_LEVEL=/W3
!ENDIF
USE_MSVCRT=1
INCLUDES=..\msvc;$(DDK_INC_PATH)
C_DEFINES = $(C_DEFINES) /DDDKBUILD $(DLL_DEFINES)
LINKER_FLAGS=/ignore:4006
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\advapi32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\shell32.lib \
$(SDK_LIB_PATH)\setupapi.lib \
$(SDK_LIB_PATH)\ole32.lib
SOURCES=logging.c \
libwdi.c \
libwdi_dlg.c \
tokenizer.c \
vid_data.c \
libwdi.rc
@@ -0,0 +1,218 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="libwdi (static)"
ProjectGUID="{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}"
RootNamespace="libwdi"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\libwdi"
ConfigurationType="4"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Embedding binary resources"
CommandLine="$(TargetDir)\..\helper\embedder $(InputDir)\embedded.h"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;OPT_M64;OPT_M32;USER_DIR=\&quot;\&quot;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="E:\WinDDK\7600.16385.0"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib"
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\libwdi"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Embedding binary resources"
CommandLine="$(TargetDir)\..\helper\embedder $(InputDir)\embedded.h"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\msvc"
PreprocessorDefinitions="_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;OPT_M64;OPT_M32;USER_DIR=\&quot;\&quot;"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="E:\WinDDK\7600.16385.0"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\libwdi.c"
>
</File>
<File
RelativePath=".\libwdi_dlg.c"
>
</File>
<File
RelativePath=".\logging.c"
>
</File>
<File
RelativePath=".\tokenizer.c"
>
</File>
<File
RelativePath=".\vid_data.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\msvc\config.h"
>
</File>
<File
RelativePath=".\installer.h"
>
</File>
<File
RelativePath=".\libwdi.h"
>
</File>
<File
RelativePath=".\logging.h"
>
</File>
<File
RelativePath=".\tokenizer.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
>
<File
RelativePath=".\libusb-win32.inf.in"
>
</File>
<File
RelativePath=".\winusb.inf.in"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libwdi (static)</ProjectName>
<ProjectGuid>{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}</ProjectGuid>
<RootNamespace>libwdi</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\lib\libwdi\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\lib\libwdi\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PreBuildEvent>
<Message>Embedding binary resources</Message>
<Command>$(TargetDir)\..\helper\embedder $(ProjectDir)\embedded.h</Command>
</PreBuildEvent>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;OPT_M64;OPT_M32;USER_DIR="";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>E:\WinDDK\7600.16385.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PreBuildEvent>
<Message>Embedding binary resources</Message>
<Command>$(TargetDir)\..\helper\embedder $(ProjectDir)\embedded.h</Command>
</PreBuildEvent>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;OPT_M64;OPT_M32;USER_DIR="";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>E:\WinDDK\7600.16385.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="libwdi.c" />
<ClCompile Include="libwdi_dlg.c" />
<ClCompile Include="logging.c" />
<ClCompile Include="tokenizer.c" />
<ClCompile Include="vid_data.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\msvc\config.h" />
<ClInclude Include="installer.h" />
<ClInclude Include="libwdi.h" />
<ClInclude Include="logging.h" />
<ClInclude Include="tokenizer.h" />
</ItemGroup>
<ItemGroup>
<None Include="libusb-win32.inf.in" />
<None Include="winusb.inf.in" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="embedder_2008.vcxproj">
<Project>{792d44d5-28a7-4eb3-b84b-8021fe3189f9}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="installer_x64_2008.vcxproj">
<Project>{e5a56ee0-182f-470f-8cdc-8c1b7b86ee26}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="installer_x86_2008.vcxproj">
<Project>{9b1c561e-f95b-4849-a7aa-a4350e227c20}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{8a69c287-59a1-4d2d-87e8-7357b561fe4f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="libwdi.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="libwdi_dlg.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="logging.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tokenizer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vid_data.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\msvc\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="installer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="libwdi.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="logging.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="tokenizer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="libusb-win32.inf.in">
<Filter>Resource Files</Filter>
</None>
<None Include="winusb.inf.in">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
@@ -0,0 +1,331 @@
/*
* libwdi logging functions
* Copyright (c) Johannes Erdfelt, Daniel Drake et al.
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <windows.h>
#include <config.h>
#include <stdarg.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <stdint.h>
#include "libwdi.h"
#include "logging.h"
HANDLE logger_rd_handle = INVALID_HANDLE_VALUE;
HANDLE logger_wr_handle = INVALID_HANDLE_VALUE;
// Handle and Message for the destination Window when registered
HWND logger_dest = NULL;
UINT logger_msg = 0;
// Detect spurious log readouts
unsigned log_messages_pending = 0;
// Global debug level
static int global_log_level = WDI_LOG_LEVEL_INFO;
extern char *windows_error_str(uint32_t retval);
void pipe_wdi_log_v(enum wdi_log_level level,
const char *function, const char *format, va_list args)
{
char buffer[LOGBUF_SIZE];
DWORD junk;
int size1, size2;
bool truncated = false;
const char* prefix;
const char* truncation_notice = "TRUNCATION detected for above line - Please "
"send this log excerpt to the libwdi developers so we can fix it.";
if (logger_wr_handle == INVALID_HANDLE_VALUE)
return;
#ifndef ENABLE_DEBUG_LOGGING
if (level < global_log_level)
return;
#endif
switch (level) {
case WDI_LOG_LEVEL_INFO:
prefix = "info";
break;
case WDI_LOG_LEVEL_WARNING:
prefix = "warning";
break;
case WDI_LOG_LEVEL_ERROR:
prefix = "error";
break;
case WDI_LOG_LEVEL_DEBUG:
prefix = "debug";
break;
default:
prefix = "unknown";
break;
}
size1 = safe_snprintf(buffer, LOGBUF_SIZE, "libwdi:%s [%s] ", prefix, function);
size2 = 0;
if (size1 < 0) {
buffer[LOGBUF_SIZE-1] = 0;
size1 = LOGBUF_SIZE-1;
truncated = true;
} else {
size2 = safe_vsnprintf(buffer+size1, LOGBUF_SIZE-size1, format, args);
if (size2 < 0) {
buffer[LOGBUF_SIZE-1] = 0;
size2 = LOGBUF_SIZE-1-size1;
truncated = true;
}
}
// http://msdn.microsoft.com/en-us/library/aa365150%28VS.85%29.aspx:
// "if your specified buffer size is too small, the system will grow the
// buffer as needed, but the downside is that the operation will block
// until the (existing) data is read from the pipe."
// Existing pipe data should have produced a notification, but if the pipe
// is left to fill without readout, we might run into blocking log calls.
// TODO: address this potential issue if it is reported
WriteFile(logger_wr_handle, buffer, (DWORD)(size1+size2+1), &junk, NULL);
// Notify the destination window of a new log message
log_messages_pending++;
PostMessage(logger_dest, logger_msg, level, 0);
if (truncated) {
WriteFile(logger_wr_handle, truncation_notice,
(DWORD)strlen(truncation_notice)+1, &junk, NULL);
log_messages_pending++;
PostMessage(logger_dest, logger_msg, (WPARAM)level, 0);
}
}
void console_wdi_log_v(enum wdi_log_level level,
const char *function, const char *format, va_list args)
{
FILE *stream;
const char *prefix;
#ifdef LOG_OUTPUT_DEBUGWINDOW
char fmt[LOGBUF_SIZE];
char buf[LOGBUF_SIZE];
#endif
stream = stdout;
#ifndef ENABLE_DEBUG_LOGGING
if (level < global_log_level)
return;
#endif
switch (level) {
case WDI_LOG_LEVEL_INFO:
prefix = "info";
break;
case WDI_LOG_LEVEL_WARNING:
stream = stderr;
prefix = "warning";
break;
case WDI_LOG_LEVEL_ERROR:
stream = stderr;
prefix = "error";
break;
case WDI_LOG_LEVEL_DEBUG:
stream = stderr;
prefix = "debug";
break;
default:
stream = stderr;
prefix = "unknown";
break;
}
#ifdef LOG_OUTPUT_DEBUGWINDOW
safe_snprintf(fmt, LOGBUF_SIZE, "libwdi:%s [%s] %s\n", prefix, function, format);
safe_vsnprintf(buf,LOGBUF_SIZE, fmt, args);
OutputDebugStringA(buf);
#else
fprintf(stream, "libwdi:%s [%s] ", prefix, function);
vfprintf(stream, format, args);
fprintf(stream, "\n");
#endif
}
void wdi_log(enum wdi_log_level level,
const char *function, const char *format, ...)
{
va_list args;
va_start (args, format);
if (logger_dest != NULL) {
pipe_wdi_log_v(level, function, format, args);
} else {
console_wdi_log_v(level, function, format, args);
}
va_end (args);
}
// Create a synchronous pipe for messaging
int create_logger(DWORD buffsize)
{
if (buffsize == 0) {
buffsize = LOGGER_PIPE_SIZE;
}
if (logger_wr_handle != INVALID_HANDLE_VALUE) {
// We (supposedly) don't have logging, so try to reach a stderr
fprintf(stderr, "trying to recreate logger pipe\n");
return WDI_ERROR_EXISTS;
}
// Read end of the pipe
logger_rd_handle = CreateNamedPipe(LOGGER_PIPE_NAME, PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE, 1, buffsize, buffsize, 0, NULL);
if (logger_rd_handle == INVALID_HANDLE_VALUE) {
fprintf(stderr, "could not create logger pipe for reading: %s\n", windows_error_str(0));
return WDI_ERROR_RESOURCE;
}
// Write end of the pipe
logger_wr_handle = CreateFile(LOGGER_PIPE_NAME, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (logger_wr_handle == INVALID_HANDLE_VALUE) {
fprintf(stderr, "could not create logger pipe for writing: %s\n", windows_error_str(0));
CloseHandle(logger_rd_handle);
logger_rd_handle = INVALID_HANDLE_VALUE;
return WDI_ERROR_RESOURCE;
}
log_messages_pending = 0;
return WDI_SUCCESS;
}
// Destroy the logging pipe
void destroy_logger(void)
{
if (logger_wr_handle != INVALID_HANDLE_VALUE) {
CloseHandle(logger_wr_handle);
logger_wr_handle = INVALID_HANDLE_VALUE;
}
if (logger_rd_handle != INVALID_HANDLE_VALUE) {
CloseHandle(logger_rd_handle);
logger_rd_handle = INVALID_HANDLE_VALUE;
}
}
/*
* Register a Window as destination for logging message
* This Window will be notified with a message event and should call
* wdi_read_logger() to retreive the message data
*/
int LIBWDI_API wdi_register_logger(HWND hWnd, UINT message, DWORD buffsize)
{
int r;
MUTEX_START;
if (logger_dest != NULL) {
MUTEX_RETURN WDI_ERROR_EXISTS;
}
r = create_logger(buffsize);
if (r == WDI_SUCCESS) {
logger_dest = hWnd;
logger_msg = message;
}
MUTEX_RETURN r;
}
/*
* Unregister a Window as destination for logging message
*/
int LIBWDI_API wdi_unregister_logger(HWND hWnd)
{
MUTEX_START;
if (logger_dest == NULL) {
MUTEX_RETURN WDI_SUCCESS;
}
if (logger_dest != hWnd) {
MUTEX_RETURN WDI_ERROR_INVALID_PARAM;
}
destroy_logger();
logger_dest = NULL;
logger_msg = 0;
MUTEX_RETURN WDI_SUCCESS;
}
/*
* Read a log message
*/
int LIBWDI_API wdi_read_logger(char* buffer, DWORD buffer_size, DWORD* message_size)
{
int size;
DWORD r;
MUTEX_START;
if ( (logger_rd_handle == INVALID_HANDLE_VALUE) && (create_logger(0) != WDI_SUCCESS) ) {
*message_size = 0;
MUTEX_RETURN WDI_ERROR_NOT_FOUND;
}
if (log_messages_pending == 0) {
size = safe_snprintf(buffer, buffer_size, "ERROR: log buffer is empty");
if (size <0) {
buffer[buffer_size-1] = 0;
MUTEX_RETURN buffer_size;
}
*message_size = (DWORD)size;
MUTEX_RETURN WDI_SUCCESS;
}
log_messages_pending--;
if (ReadFile(logger_rd_handle, (void*)buffer, buffer_size, message_size, NULL)) {
MUTEX_RETURN WDI_SUCCESS;
}
*message_size = 0;
r = GetLastError();
if ((r == ERROR_INSUFFICIENT_BUFFER) || (r == ERROR_MORE_DATA)) {
MUTEX_RETURN WDI_ERROR_OVERFLOW;
}
MUTEX_RETURN WDI_ERROR_IO;
}
/*
* Set the global log level. Only works if ENABLE_DEBUG_LOGGING is not set
*/
int LIBWDI_API wdi_set_log_level(int level)
{
#if defined(ENABLE_DEBUG_LOGGING)
return WDI_ERROR_NOT_SUPPORTED;
#endif
if ( (level < WDI_LOG_LEVEL_DEBUG) || (level > WDI_LOG_LEVEL_ERROR) ) {
return WDI_ERROR_INVALID_PARAM;
}
global_log_level = level;
return WDI_SUCCESS;
}
@@ -0,0 +1,93 @@
/*
* libwdi logging functions
* Copyright (c) Johannes Erdfelt, Daniel Drake et al.
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#define LOGGER_PIPE_NAME "\\\\.\\pipe\\libwdi-logger"
#define LOGGER_PIPE_SIZE 8192
#define LOGBUF_SIZE 512
// Prevent two exclusive libwdi calls from running at the same time
#define MUTEX_START char mutex_name[10+sizeof(__FUNCTION__)]; HANDLE mutex; \
safe_snprintf(mutex_name, 10+sizeof(__FUNCTION__), "Global\\%s", __FUNCTION__); \
mutex = CreateMutex(NULL, TRUE, mutex_name); \
if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) return WDI_ERROR_BUSY
#define MUTEX_RETURN CloseHandle(mutex); return
#if defined(_MSC_VER)
#define safe_vsnprintf(buf, size, format, arg) _vsnprintf_s(buf, size, _TRUNCATE, format, arg)
#define safe_snprintf(buf, size, ...) _snprintf_s(buf, size, _TRUNCATE, __VA_ARGS__)
#else
#define safe_vsnprintf vsnprintf
#define safe_snprintf snprintf
#endif
#if !defined(_MSC_VER) || _MSC_VER > 1200
#if defined(ENABLE_DEBUG_LOGGING) || defined(INCLUDE_DEBUG_LOGGING)
#define _wdi_log(level, ...) wdi_log(level, __FUNCTION__, __VA_ARGS__)
#else
#define _wdi_log(level, ...)
#endif
#if defined(ENABLE_DEBUG_LOGGING) || defined(INCLUDE_DEBUG_LOGGING)
#define wdi_dbg(...) _wdi_log(WDI_LOG_LEVEL_DEBUG, __VA_ARGS__)
#else
#define wdi_dbg(...)
#endif
#define wdi_info(...) _wdi_log(WDI_LOG_LEVEL_INFO, __VA_ARGS__)
#define wdi_warn(...) _wdi_log(WDI_LOG_LEVEL_WARNING, __VA_ARGS__)
#define wdi_err(...) _wdi_log(WDI_LOG_LEVEL_ERROR, __VA_ARGS__)
#else /* !defined(_MSC_VER) || _MSC_VER > 1200 */
void wdi_log_v(enum wdi_log_level level,
const char *function, const char *format, va_list args);
#if defined(ENABLE_DEBUG_LOGGING) || defined(INCLUDE_DEBUG_LOGGING)
#define LOG_BODY(level) \
{ \
va_list args; \
va_start (args, format); \
wdi_log_v(level, "", format, args); \
va_end(args); \
}
#else
#define LOG_BODY(level) { }
#endif
void inline wdi_info(const char *format, ...)
LOG_BODY(LOG_LEVEL_INFO)
void inline wdi_warn(const char *format, ...)
LOG_BODY(LOG_LEVEL_WARNING)
void inline wdi_err( const char *format, ...)
LOG_BODY(LOG_LEVEL_ERROR)
void inline wdi_dbg(const char *format, ...)
#if defined(ENABLE_DEBUG_LOGGING) || defined(INCLUDE_DEBUG_LOGGING)
LOG_BODY(LOG_LEVEL_DEBUG)
#else
{ }
#endif
#endif /* !defined(_MSC_VER) || _MSC_VER > 1200 */
extern void wdi_log(enum wdi_log_level level, const char *function, const char *format, ...);
@@ -0,0 +1,536 @@
/*
* MSAPI_UTF8: Common API calls using UTF-8 strings
* Compensating for what Microsoft should have done a long long time ago.
*
* Copyright (c) 2010 Pete Batard <pbatard@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <windows.h>
#include <shlobj.h>
#include <commdlg.h>
#include <shellapi.h>
#include <setupapi.h>
#ifdef __cplusplus
extern "C" {
#endif
#define wchar_to_utf8_no_alloc(wsrc, dest, dest_size) \
WideCharToMultiByte(CP_UTF8, 0, wsrc, -1, dest, dest_size, NULL, NULL)
#define utf8_to_wchar_no_alloc(src, wdest, wdest_size) \
MultiByteToWideChar(CP_UTF8, 0, src, -1, wdest, wdest_size)
#define Edit_ReplaceSelU(hCtrl, str) ((void)SendMessageLU(hCtrl, EM_REPLACESEL, (WPARAM)FALSE, str))
#define ComboBox_AddStringU(hCtrl, str) ((int)(DWORD)SendMessageLU(hCtrl, CB_ADDSTRING, (WPARAM)FALSE, str))
#define ComboBox_GetTextU(hCtrl, str, max_str) GetWindowTextU(hCtrl, str, max_str)
#define GetSaveFileNameU(p) GetOpenSaveFileNameU(p, TRUE)
#define GetOpenFileNameU(p) GetOpenSaveFileNameU(p, FALSE)
#define ListView_SetItemTextU(hwndLV,i,iSubItem_,pszText_) { LVITEMW _ms_wlvi; _ms_wlvi.iSubItem = iSubItem_; \
_ms_wlvi.pszText = utf8_to_wchar(pszText_); \
SNDMSG((hwndLV),LVM_SETITEMTEXTW,(WPARAM)(i),(LPARAM)&_ms_wlvi); sfree(_ms_wlvi.pszText);}
#define sfree(p) do {if (p != NULL) {free((void*)(p)); p = NULL;}} while(0)
#define wconvert(p) wchar_t* w ## p = utf8_to_wchar(p)
#define walloc(p, size) wchar_t* w ## p = calloc(size, sizeof(wchar_t))
#define wfree(p) sfree(w ## p)
/*
* Converts an UTF-16 string to UTF8 (allocate returned string)
* Returns NULL on error
*/
static __inline char* wchar_to_utf8(const wchar_t* wstr)
{
int size = 0;
char* str = NULL;
// Find out the size we need to allocate for our converted string
size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
if (size <= 1) // An empty string would be size 1
return NULL;
if ((str = (char*)calloc(size, 1)) == NULL)
return NULL;
if (wchar_to_utf8_no_alloc(wstr, str, size) != size) {
sfree(str);
return NULL;
}
return str;
}
/*
* Converts an UTF8 string to UTF-16 (allocate returned string)
* Returns NULL on error
*/
static __inline wchar_t* utf8_to_wchar(const char* str)
{
int size = 0;
wchar_t* wstr = NULL;
// Find out the size we need to allocate for our converted string
size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
if (size <= 1) // An empty string would be size 1
return NULL;
if ((wstr = (wchar_t*)calloc(size, sizeof(wchar_t))) == NULL)
return NULL;
if (utf8_to_wchar_no_alloc(str, wstr, size) != size) {
sfree(wstr);
return NULL;
}
return wstr;
}
static __inline DWORD FormatMessageU(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId,
DWORD dwLanguageId, char* lpBuffer, DWORD nSize, va_list *Arguments)
{
DWORD ret = 0, err = ERROR_INVALID_DATA;
walloc(lpBuffer, nSize);
ret = FormatMessageW(dwFlags, lpSource, dwMessageId, dwLanguageId, wlpBuffer, nSize, Arguments);
err = GetLastError();
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, nSize)) == 0)) {
err = GetLastError();
ret = 0;
}
wfree(lpBuffer);
SetLastError(err);
return ret;
}
// SendMessage, with LPARAM as UTF-8 string
static __inline LRESULT SendMessageLU(HWND hWnd, UINT Msg, WPARAM wParam, const char* lParam)
{
LRESULT ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
wconvert(lParam);
ret = SendMessageW(hWnd, Msg, wParam, (LPARAM)wlParam);
err = GetLastError();
wfree(lParam);
SetLastError(err);
return ret;
}
static __inline BOOL SHGetPathFromIDListU(LPCITEMIDLIST pidl, char* pszPath)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
walloc(pszPath, MAX_PATH);
ret = SHGetPathFromIDListW(pidl, wpszPath);
err = GetLastError();
if ((ret) && (wchar_to_utf8_no_alloc(wpszPath, pszPath, MAX_PATH) == 0)) {
err = GetLastError();
ret = FALSE;
}
wfree(pszPath);
SetLastError(err);
return ret;
}
static __inline HWND CreateWindowU(char* lpClassName, char* lpWindowName,
DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent,
HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
HWND ret = NULL;
DWORD err = ERROR_INVALID_DATA;
wconvert(lpClassName);
wconvert(lpWindowName);
ret = CreateWindowW(wlpClassName, wlpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
err = GetLastError();
wfree(lpClassName);
wfree(lpWindowName);
SetLastError(err);
return ret;
}
static __inline int GetWindowTextU(HWND hWnd, char* lpString, int nMaxCount)
{
int ret = 0;
DWORD err = ERROR_INVALID_DATA;
walloc(lpString, nMaxCount);
ret = GetWindowTextW(hWnd, wlpString, nMaxCount);
err = GetLastError();
if ( (ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpString, lpString, nMaxCount)) == 0) ) {
err = GetLastError();
}
wfree(lpString);
SetLastError(err);
return ret;
}
static __inline BOOL SetWindowTextU(HWND hWnd, const char* lpString)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
wconvert(lpString);
ret = SetWindowTextW(hWnd, wlpString);
err = GetLastError();
wfree(lpString);
SetLastError(err);
return ret;
}
static __inline int GetWindowTextLengthU(HWND hWnd)
{
int ret = 0;
DWORD err = ERROR_INVALID_DATA;
wchar_t* wbuf = NULL;
char* buf = NULL;
ret = GetWindowTextLengthW(hWnd);
err = GetLastError();
if (ret == 0) goto out;
wbuf = calloc(ret, sizeof(wchar_t));
err = GetLastError();
if (wbuf == NULL) {
err = ERROR_OUTOFMEMORY; ret = 0; goto out;
}
ret = GetWindowTextW(hWnd, wbuf, ret);
err = GetLastError();
if (ret == 0) goto out;
buf = wchar_to_utf8(wbuf);
err = GetLastError();
if (buf == NULL) {
err = ERROR_OUTOFMEMORY; ret = 0; goto out;
}
ret = (int)strlen(buf) + 2; // GetDlgItemText seems to add a character
err = GetLastError();
out:
sfree(wbuf);
sfree(buf);
return ret;
}
static __inline UINT GetDlgItemTextU(HWND hDlg, int nIDDlgItem, char* lpString, int nMaxCount)
{
UINT ret = 0;
DWORD err = ERROR_INVALID_DATA;
walloc(lpString, nMaxCount);
ret = GetDlgItemTextW(hDlg, nIDDlgItem, wlpString, nMaxCount);
err = GetLastError();
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpString, lpString, nMaxCount)) == 0)) {
err = GetLastError();
}
wfree(lpString);
SetLastError(err);
return ret;
}
static __inline BOOL SetDlgItemTextU(HWND hDlg, int nIDDlgItem, const char* lpString)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
wconvert(lpString);
ret = SetDlgItemTextW(hDlg, nIDDlgItem, wlpString);
err = GetLastError();
wfree(lpString);
SetLastError(err);
return ret;
}
static __inline HANDLE CreateFileU(const char* lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE ret = INVALID_HANDLE_VALUE;
DWORD err = ERROR_INVALID_DATA;
wconvert(lpFileName);
ret = CreateFileW(wlpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
err = GetLastError();
wfree(lpFileName);
SetLastError(err);
return ret;
}
// This function differs from regular GetTextExtentPoint in that it uses a zero terminated string
static __inline BOOL GetTextExtentPointU(HDC hdc, const char* lpString, LPSIZE lpSize)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
wconvert(lpString);
ret = GetTextExtentPointW(hdc, wlpString, (int)wcslen(wlpString)+1, lpSize);
err = GetLastError();
wfree(lpString);
SetLastError(err);
return ret;
}
static __inline DWORD GetCurrentDirectoryU(DWORD nBufferLength, char* lpBuffer)
{
DWORD ret = 0, err = ERROR_INVALID_DATA;
walloc(lpBuffer, nBufferLength);
ret = GetCurrentDirectoryW(nBufferLength, wlpBuffer);
err = GetLastError();
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, nBufferLength)) == 0)) {
err = GetLastError();
}
wfree(lpBuffer);
SetLastError(err);
return ret;
}
static __inline DWORD GetFullPathNameU(const char* lpFileName, DWORD nBufferLength, char* lpBuffer, char** lpFilePart)
{
DWORD ret = 0, err = ERROR_INVALID_DATA;
wchar_t* wlpFilePart;
wconvert(lpFileName);
walloc(lpBuffer, nBufferLength);
// lpFilePart is not supported
if (lpFilePart != NULL) goto out;
ret = GetFullPathNameW(wlpFileName, nBufferLength, wlpBuffer, &wlpFilePart);
err = GetLastError();
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, nBufferLength)) == 0)) {
err = GetLastError();
}
out:
wfree(lpBuffer);
wfree(lpFileName);
SetLastError(err);
return ret;
}
static __inline DWORD GetFileAttributesU(const char* lpFileName)
{
DWORD ret = 0xFFFFFFFF, err = ERROR_INVALID_DATA;
wconvert(lpFileName);
ret = GetFileAttributesW(wlpFileName);
err = GetLastError();
wfree(lpFileName);
SetLastError(err);
return ret;
}
static __inline int SHCreateDirectoryExU(HWND hwnd, const char* pszPath, SECURITY_ATTRIBUTES *psa)
{
int ret = ERROR_INVALID_DATA;
DWORD err = ERROR_INVALID_DATA;
wconvert(pszPath);
ret = SHCreateDirectoryExW(hwnd, wpszPath, psa);
err = GetLastError();
wfree(pszPath);
SetLastError(err);
return ret;
}
static __inline BOOL ShellExecuteExU(SHELLEXECUTEINFOA* lpExecInfo)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
SHELLEXECUTEINFOW wExecInfo;
// Because we're lazy, we'll assume that the A and W structs inherently have the same size
if (lpExecInfo->cbSize != sizeof(SHELLEXECUTEINFOW)) {
SetLastError(ERROR_BAD_LENGTH); return FALSE;
}
memcpy(&wExecInfo, lpExecInfo, lpExecInfo->cbSize);
wExecInfo.lpVerb = utf8_to_wchar(lpExecInfo->lpVerb);
wExecInfo.lpFile = utf8_to_wchar(lpExecInfo->lpFile);
wExecInfo.lpParameters = utf8_to_wchar(lpExecInfo->lpParameters);
wExecInfo.lpDirectory = utf8_to_wchar(lpExecInfo->lpDirectory);
if (wExecInfo.fMask & SEE_MASK_CLASSNAME) {
wExecInfo.lpClass = utf8_to_wchar(lpExecInfo->lpClass);
} else {
wExecInfo.lpClass = NULL;
}
ret = ShellExecuteExW(&wExecInfo);
err = GetLastError();
// Copy the returned values back
lpExecInfo->hInstApp = wExecInfo.hInstApp;
lpExecInfo->hProcess = wExecInfo.hProcess;
sfree(wExecInfo.lpVerb);
sfree(wExecInfo.lpFile);
sfree(wExecInfo.lpParameters);
sfree(wExecInfo.lpDirectory);
sfree(wExecInfo.lpClass);
SetLastError(err);
return ret;
}
// Doesn't support LPSTARTUPINFOEX struct
static __inline BOOL CreateProcessU(const char* lpApplicationName, const char* lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags,
LPVOID lpEnvironment, const char* lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
STARTUPINFOW wStartupInfo;
wconvert(lpApplicationName);
wconvert(lpCommandLine);
wconvert(lpCurrentDirectory);
// Because we're lazy, we'll assume that the A and W structs inherently have the same size
// Also prevents the use of STARTUPINFOEX
if (lpStartupInfo->cb != sizeof(STARTUPINFOW)) {
err = ERROR_BAD_LENGTH; goto out;
}
memcpy(&wStartupInfo, lpStartupInfo, lpStartupInfo->cb);
wStartupInfo.lpDesktop = utf8_to_wchar(lpStartupInfo->lpDesktop);
wStartupInfo.lpTitle = utf8_to_wchar(lpStartupInfo->lpTitle);
ret = CreateProcessW(wlpApplicationName, wlpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles,
dwCreationFlags, lpEnvironment, wlpCurrentDirectory, &wStartupInfo, lpProcessInformation);
err = GetLastError();
sfree(wStartupInfo.lpDesktop);
sfree(wStartupInfo.lpTitle);
out:
wfree(lpApplicationName);
wfree(lpCommandLine);
wfree(lpCurrentDirectory);
return ret;
}
// NOTE: when used, nFileOffset & nFileExtension MUST be provided
// in number of Unicode characters, NOT number of UTF-8 bytes
static __inline BOOL WINAPI GetOpenSaveFileNameU(LPOPENFILENAMEA lpofn, BOOL save)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
size_t i, len;
OPENFILENAMEW wofn;
memset(&wofn, 0, sizeof(wofn));
wofn.lStructSize = sizeof(wofn);
wofn.hwndOwner = lpofn->hwndOwner;
wofn.hInstance = lpofn->hInstance;
// No support for custom filters
if (lpofn->lpstrCustomFilter != NULL) goto out;
// Count on Microsoft to use an moronic scheme for filters
// that relies on NULL separators and double NULL terminators
if (lpofn->lpstrFilter != NULL) {
// Replace the NULLs by something that can be converted
for (i=0; ; i++) {
if (lpofn->lpstrFilter[i] == 0) {
((char*)lpofn->lpstrFilter)[i] = '\r';
if (lpofn->lpstrFilter[i+1] == 0) {
break;
}
}
}
wofn.lpstrFilter = utf8_to_wchar(lpofn->lpstrFilter);
// And revert
len = wcslen(wofn.lpstrFilter); // don't use in the loop as it would be reevaluated
for (i=0; i<len; i++) {
if (wofn.lpstrFilter[i] == '\r') {
((wchar_t*)wofn.lpstrFilter)[i] = 0;
}
}
len = strlen(lpofn->lpstrFilter);
for (i=0; i<len; i++) {
if (lpofn->lpstrFilter[i] == '\r') {
((char*)lpofn->lpstrFilter)[i] = 0;
}
}
} else {
wofn.lpstrFilter = NULL;
}
wofn.nMaxCustFilter = lpofn->nMaxCustFilter;
wofn.nFilterIndex = lpofn->nFilterIndex;
wofn.lpstrFile = calloc(lpofn->nMaxFile, sizeof(wchar_t));
utf8_to_wchar_no_alloc(lpofn->lpstrFile, wofn.lpstrFile, lpofn->nMaxFile);
wofn.nMaxFile = lpofn->nMaxFile;
wofn.lpstrFileTitle = calloc(lpofn->nMaxFileTitle, sizeof(wchar_t));
utf8_to_wchar_no_alloc(lpofn->lpstrFileTitle, wofn.lpstrFileTitle, lpofn->nMaxFileTitle);
wofn.nMaxFileTitle = lpofn->nMaxFileTitle;
wofn.lpstrInitialDir = utf8_to_wchar(lpofn->lpstrInitialDir);
wofn.lpstrTitle = utf8_to_wchar(lpofn->lpstrTitle);
wofn.Flags = lpofn->Flags;
wofn.nFileOffset = lpofn->nFileOffset;
wofn.nFileExtension = lpofn->nFileExtension;
wofn.lpstrDefExt = utf8_to_wchar(lpofn->lpstrDefExt);
wofn.lCustData = lpofn->lCustData;
wofn.lpfnHook = lpofn->lpfnHook;
wofn.lpTemplateName = utf8_to_wchar(lpofn->lpTemplateName);
wofn.pvReserved = lpofn->pvReserved;
wofn.dwReserved = lpofn->dwReserved;
wofn.FlagsEx = lpofn->FlagsEx;
if (save) {
ret = GetSaveFileNameW(&wofn);
} else {
ret = GetOpenFileNameW(&wofn);
}
err = GetLastError();
if ( (ret)
&& ( (wchar_to_utf8_no_alloc(wofn.lpstrFile, lpofn->lpstrFile, lpofn->nMaxFile) == 0)
|| (wchar_to_utf8_no_alloc(wofn.lpstrFileTitle, lpofn->lpstrFileTitle, lpofn->nMaxFileTitle) == 0) ) ) {
err = GetLastError();
ret = FALSE;
}
out:
sfree(wofn.lpstrDefExt);
sfree(wofn.lpstrFile);
sfree(wofn.lpstrFileTitle);
sfree(wofn.lpstrFilter);
sfree(wofn.lpstrInitialDir);
sfree(wofn.lpstrTitle);
sfree(wofn.lpTemplateName);
SetLastError(err);
return ret;
}
extern BOOL WINAPI UpdateDriverForPlugAndPlayDevicesW(HWND hwndParent, LPCWSTR HardwareId,
LPCWSTR FullInfPath, DWORD InstallFlags, PBOOL bRebootRequired);
static __inline BOOL UpdateDriverForPlugAndPlayDevicesU(HWND hwndParent, const char* HardwareId, const char* FullInfPath,
DWORD InstallFlags, PBOOL bRebootRequired)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
wconvert(HardwareId);
wconvert(FullInfPath);
ret = UpdateDriverForPlugAndPlayDevicesW(hwndParent, wHardwareId, wFullInfPath, InstallFlags, bRebootRequired);
err = GetLastError();
wfree(HardwareId);
wfree(FullInfPath);
SetLastError(err);
return ret;
}
static __inline BOOL SetupCopyOEMInfU(const char* SourceInfFileName, const char* OEMSourceMediaLocation, DWORD OEMSourceMediaType,
DWORD CopyStyle, char* DestinationInfFileName, DWORD DestinationInfFileNameSize,
PDWORD RequiredSize, PTSTR DestinationInfFileNameComponent)
{
BOOL ret = FALSE;
DWORD err = ERROR_INVALID_DATA;
wconvert(SourceInfFileName);
wconvert(OEMSourceMediaLocation);
walloc(DestinationInfFileName, DestinationInfFileNameSize);
// DestinationInfFileNameComponent is not supported
if (DestinationInfFileNameComponent != NULL) goto out;
ret = SetupCopyOEMInfW(wSourceInfFileName, wOEMSourceMediaLocation, OEMSourceMediaType, CopyStyle,
wDestinationInfFileName, DestinationInfFileNameSize, RequiredSize, NULL);
err = GetLastError();
if ((ret != FALSE) && ((ret = wchar_to_utf8_no_alloc(wDestinationInfFileName, DestinationInfFileName, DestinationInfFileNameSize)) == 0)) {
err = GetLastError();
}
out:
wfree(SourceInfFileName);
wfree(OEMSourceMediaLocation);
wfree(DestinationInfFileName);
SetLastError(err);
return ret;
}
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by libwdi.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
@@ -0,0 +1,35 @@
TARGETTYPE=LIBRARY
#TARGETTYPE is not defined, to allow selection between static lib or DLL with ddk_build
TARGETNAME=libwdi
#Must be set, else DLL build will look for libwdi.def
DLLDEF=
#DLL_EXPORT must be provided as a macro when buidling a DLL
!IF "$(TARGETTYPE)"=="DYNLINK"
DLL_DEFINES=/DDLL_EXPORT
!ENDIF
!IFNDEF MSC_WARNING_LEVEL
MSC_WARNING_LEVEL=/W3
!ENDIF
USE_MSVCRT=1
INCLUDES=..\msvc;$(DDK_INC_PATH)
C_DEFINES = $(C_DEFINES) /DDDKBUILD $(DLL_DEFINES)
LINKER_FLAGS=/ignore:4006
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\advapi32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\shell32.lib \
$(SDK_LIB_PATH)\setupapi.lib \
$(SDK_LIB_PATH)\ole32.lib
SOURCES=logging.c \
libwdi.c \
libwdi_dlg.c \
tokenizer.c \
vid_data.c \
libwdi.rc

@@ -0,0 +1,234 @@
/* LIBUSB-WIN32, Generic Windows USB Library
* Copyright (c) 2010 Travis Robinson <libusbdotnet@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
08/05/2010 Revisions:
o minor string macro improvements
07/23/2010 Revisions:
o Fixed positive return value if memory allocation fails
o Changed grow size from 8192 to 1024
*/
#include "tokenizer.h"
#include <stdlib.h>
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
#define safe_strncpy(dst, dst_max, src, count) strncpy(dst, src, safe_min(count, dst_max - 1))
// If the dst buffer is to small it grows to what is needed+GROW_SIZE
#define GetDestSize(RequiredSize) RequiredSize+1024
BOOL grow_strcpy(char** DstPtr, char** DstPtrOrig, long* DstPos, long* DstAllocSize,
const char* ReplaceString, long ReplaceLength)
{
if ((*DstPos)+(ReplaceLength) >= (*DstAllocSize))
{
*DstAllocSize = GetDestSize((*DstPos) + ReplaceLength);
*DstPtr = realloc((*DstPtr),(*DstAllocSize));
}
if (!(*DstPtr))
{
free((*DstPtrOrig));
return FALSE;
}
*DstPtrOrig = (*DstPtr);
safe_strncpy(((*DstPtr)+(*DstPos)),(*DstAllocSize)-(*DstPos), ReplaceString, ReplaceLength);
*DstPos += ReplaceLength;
return TRUE;
}
// replaces tokens in text.
// Returns: less than 0 on error, 0 if src is empty,
// number of chars written to dst on success.
// NOTE: On success dst must be freed by the calling function.
long tokenize_string(const char* src, // text to bo tokenized
long src_count, // length of src
char** dst, // destination buffer (must be freed)
const token_entity_t* token_entities, // match/replace token list
const char* tok_prefix, // the token prefix exmpl:"$("
const char* tok_suffix, // the token suffix exmpl:")"
int recursive) // allows tokenzing tokens in tokens
{
const token_entity_t* next_match;
long match_replace_pos;
const char* match_start;
long tok_prefix_size;
long tok_suffix_size;
int match_found;
long match_length;
long replace_length;
long dst_pos;
long dst_alloc_size;
char* pDst;
long match_count;
if (!src || !dst || !token_entities || !src_count || !tok_prefix || !tok_suffix)
return -ERROR_BAD_ARGUMENTS;
tok_prefix_size = (long)strlen(tok_prefix);
tok_suffix_size = (long)strlen(tok_suffix);
// token prefix and suffix markers is required
if (!tok_prefix_size || !tok_suffix_size)
return -ERROR_BAD_ARGUMENTS;
// if the src buffer count <= 0 assume it is null terminated
if (src_count < 0) src_count = (long)strlen(src);
// nothing to do
if (src_count == 0) return 0;
// Set the initial buffer size.
dst_alloc_size = GetDestSize(src_count);
*dst = pDst = malloc(dst_alloc_size);
if (!pDst)
return -ERROR_NOT_ENOUGH_MEMORY;
dst_pos=0;
match_count=0;
// search for a token prefix
while((match_start=strstr(src,tok_prefix)))
{
// found a token prefix
match_replace_pos=0;
match_found=0;
match_length = (long)(match_start-src);
// copy all the text up to the tok_prefix start from src to dst.
if (!grow_strcpy(&pDst, dst, &dst_pos, &dst_alloc_size, src, match_length))
{
return -ERROR_NOT_ENOUGH_MEMORY;
}
src+=match_length+tok_prefix_size;
src_count-=(match_length+tok_prefix_size);
//ASSERT(src_count >=0);
// If src_count equals 0 this is a token prefix and the end of src.
if (src_count > 0)
{
// iterate through the match/replace tokens
while ((next_match=&token_entities[match_replace_pos++]))
{
// the match and replace fields must both be set
if (!next_match->match || !next_match->replace)
{
break;
}
match_length=(long)strlen(next_match->match);
// if this token will be longer than what's left in src buffer, skip it.
if (src_count < (match_length+tok_suffix_size))
continue; // not found
// check for a match suffix
if (strncmp(src+match_length,tok_suffix,tok_suffix_size)!=0)
continue; // not found
if (strncmp(src,next_match->match,match_length)==0)
{
// found a valid token match
replace_length=(long)strlen(next_match->replace);
if (!grow_strcpy(&pDst, dst, &dst_pos, &dst_alloc_size,
next_match->replace, replace_length))
{
return -ERROR_NOT_ENOUGH_MEMORY;
}
src+=match_length+tok_suffix_size;
src_count-=(match_length+tok_suffix_size);
match_found=1;
match_count++;
break;
}
}
}
if (!match_found)
{
// No matches were found; leave it as-is.
if (!grow_strcpy(&pDst, dst, &dst_pos, &dst_alloc_size,
tok_prefix, tok_prefix_size))
{
return -ERROR_NOT_ENOUGH_MEMORY;
}
}
}
match_length=src_count;
if (match_length > 0)
{
if (!grow_strcpy(&pDst, dst, &dst_pos, &dst_alloc_size, src, match_length))
{
return -ERROR_NOT_ENOUGH_MEMORY;
}
}
// grow_strcpy is aware an extra char is always needed for null.
pDst[dst_pos]='\0';
if (recursive && match_count)
{
// if recursive mode is true, keep re-tokenizing until no matches are found
*dst = NULL;
dst_pos = tokenize_string(pDst,dst_pos,dst,
token_entities,tok_prefix,tok_suffix,recursive);
// free the old dst buffer
free(pDst);
}
// return the new size (excluding null)
return dst_pos;
}
// tokenizes a resource stored in the current module.
long tokenize_resource(LPCSTR resource_name,
LPCSTR resource_type,
char** dst,
const token_entity_t* token_entities,
const char* tok_prefix,
const char* tok_suffix,
int recursive)
{
const char* src;
long src_count;
HGLOBAL res_data;
HRSRC hSrc = FindResourceA(NULL, resource_name, resource_type);
if (!hSrc)
return -ERROR_RESOURCE_DATA_NOT_FOUND;
src_count = SizeofResource(NULL, hSrc);
res_data = LoadResource(NULL,hSrc);
if (!res_data)
return -ERROR_RESOURCE_DATA_NOT_FOUND;
src = (char*) LockResource(res_data);
if (!src)
return -ERROR_RESOURCE_DATA_NOT_FOUND;
return tokenize_string(src, src_count, dst,
token_entities, tok_prefix, tok_suffix, recursive);
}
@@ -0,0 +1,46 @@
/* LIBUSB-WIN32, Generic Windows USB Library
* Copyright (c) 2010 Travis Robinson <libusbdotnet@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _TOKENIZER_H
#define _TOKENIZER_H
#include <windows.h>
typedef struct _token_entity_t
{
const char* match;
char replace[1024];
}token_entity_t;
long tokenize_string(const char* src,
long src_count,
char** dst,
const token_entity_t* token_entities,
const char* tok_prefix,
const char* tok_suffix,
int recursive);
long tokenize_resource(LPCSTR resource_name,
LPCSTR resource_type,
char** dst,
const token_entity_t* token_entities,
const char* tok_prefix,
const char* tok_suffix,
int recursive);
#endif
@@ -0,0 +1,81 @@
#!/bin/sh
echo This file recreates vid_data.c according http://www.linux-usb.org/usb.ids
echo
# check that wget and sed are available
type -P wget &>/dev/null || { echo "wget command not found. Aborting." >&2; exit 1; }
type -P sed &>/dev/null || { echo "sed command not found. Aborting." >&2; exit 1; }
# Download the latest version (overwrite previous if newer)
wget -m -nd http://www.linux-usb.org/usb.ids
# Create the sed command file
cat > cmd.sed <<\_EOF
# Header, part 1
s¦^#.*List of USB.*¦/*\
* USB vendors, by VID\
* based on http://www.linux-usb.org/usb.ids by Stephen J. Gowdy\
*\
*\
* This library is free software; you can redistribute it and/or\
* modify it under the terms of the GNU Lesser General Public\
* License as published by the Free Software Foundation; either\
* version 2.1 of the License, or (at your option) any later version.\
*\
* This library is distributed in the hope that it will be useful,\
* but WITHOUT ANY WARRANTY; without even the implied warranty of\
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\
* Lesser General Public License for more details.\
*\
* You should have received a copy of the GNU Lesser General Public\
* License along with this library; if not, write to the Free Software\
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\
*/\
\
#include <stdlib.h>\
#include "libwdi.h"\
\
struct vendor_name \{\
unsigned short vid;\
const char* name;\
\};\
\
/*\
* http://www.linux-usb.org/usb.ids¦p
# Header part 2, version
s|# Version:| * Version:|
/ \* Version:/p
# Header Part 3
s|^#.*Date:.*| \*/\
struct vendor_name usb_vendor[] = \{|p
# Footer
$a\
\};\
\
const char* LIBWDI_API wdi_get_vendor_name(unsigned short vid)\
\{\
int i;\
\
for(i=0; i<sizeof(usb_vendor)/sizeof(usb_vendor[0]); i++) \{\
if (usb_vendor[i].vid == vid) \{\
return usb_vendor[i].name;\
\}\
\}\
return NULL;\
\}
# Main Data
/^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] /!d
s/^\([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\) \(.*\)/\ { 0x\1, "\2" \},/
s/???/?/
s/??/?/
_EOF
# Run sed to generate the source.
sed -f cmd.sed usb.ids > vid_data.c
rm cmd.sed
echo Done.
@@ -0,0 +1,91 @@
; #INF_FILENAME#
; Copyright (c) 2010 libusb (GNU LGPL)
[Strings]
DeviceName = "#DEVICE_DESCRIPTION#"
VendorName = "#DEVICE_MANUFACTURER#"
SourceName = "#DEVICE_DESCRIPTION# Install Disk"
DeviceID = "#DEVICE_HARDWARE_ID#"
DeviceGUID = "#DEVICE_INTERFACE_GUID#"
[Version]
Signature = "$Windows NT$"
Class = "libusb (WinUSB) devices"
ClassGuid = {78a1c341-4539-11d3-b88d-00c04fad5171}
Provider = "libusb.org"
CatalogFile = #CAT_FILENAME#
DriverVer = #DRIVER_DATE#, #DRIVER_VERSION#
[ClassInstall32]
Addreg = WinUSBDeviceClassReg
[WinUSBDeviceClassReg]
HKR,,,0,"libusb (WinUSB) devices"
HKR,,Icon,,-20
[Manufacturer]
%VendorName% = libusbDevice_WinUSB,NTx86,NTamd64,NTia64
[libusbDevice_WinUSB.NTx86]
%DeviceName% = USB_Install, USB\%DeviceID%
[libusbDevice_WinUSB.NTamd64]
%DeviceName% = USB_Install, USB\%DeviceID%
[libusbDevice_WinUSB.NTia64]
%DeviceName% = USB_Install, USB\%DeviceID%
[USB_Install]
Include = winusb.inf
Needs = WINUSB.NT
[USB_Install.Services]
Include = winusb.inf
AddService = WinUSB,0x00000002,WinUSB_ServiceInstall
[WinUSB_ServiceInstall]
DisplayName = "WinUSB - Kernel Driver #DRIVER_DATE# #DRIVER_VERSION#"
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\WinUSB.sys
[USB_Install.Wdf]
KmdfService = WINUSB, WinUsb_Install
[WinUSB_Install]
KmdfLibraryVersion = 1.9
[USB_Install.HW]
AddReg = Dev_AddReg
[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID%
[USB_Install.CoInstallers]
AddReg = CoInstallers_AddReg
CopyFiles = CoInstallers_CopyFiles
[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"
[CoInstallers_CopyFiles]
WinUSBCoInstaller2.dll
WdfCoInstaller01009.dll
[DestinationDirs]
CoInstallers_CopyFiles = 11
[SourceDisksNames]
1 = %SourceName%
[SourceDisksFiles.x86]
WinUSBCoInstaller2.dll = 1,x86
WdfCoInstaller01009.dll = 1,x86
[SourceDisksFiles.amd64]
WinUSBCoInstaller2.dll = 1,amd64
WdfCoInstaller01009.dll = 1,amd64
[SourceDisksFiles.ia64]
WinUSBCoInstaller2.dll = 1,ia64
WdfCoInstaller01009.dll = 1,ia64
@@ -0,0 +1,117 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwdi (static)", "libwdi\libwdi_static_2008.vcproj", "{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}"
ProjectSection(ProjectDependencies) = postProject
{9B1C561E-F95B-4849-A7AA-A4350E227C20} = {9B1C561E-F95B-4849-A7AA-A4350E227C20}
{792D44D5-28A7-4EB3-B84B-8021FE3189F9} = {792D44D5-28A7-4EB3-B84B-8021FE3189F9}
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26} = {E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "embedder", "libwdi\embedder_2008.vcproj", "{792D44D5-28A7-4EB3-B84B-8021FE3189F9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zadic", "examples\zadic_2008.vcproj", "{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}"
ProjectSection(ProjectDependencies) = postProject
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9} = {9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E} = {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zadig", "examples\zadig_2008.vcproj", "{F7F7842F-2912-454E-ADF5-0B22987946E2}"
ProjectSection(ProjectDependencies) = postProject
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9} = {9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}
{2945B0AC-AB99-483F-9FDC-CF76613E3034} = {2945B0AC-AB99-483F-9FDC-CF76613E3034}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwdi (dll)", "libwdi\libwdi_dll_2008.vcproj", "{79275348-41A4-4D07-8990-4068C9594A2C}"
ProjectSection(ProjectDependencies) = postProject
{9B1C561E-F95B-4849-A7AA-A4350E227C20} = {9B1C561E-F95B-4849-A7AA-A4350E227C20}
{792D44D5-28A7-4EB3-B84B-8021FE3189F9} = {792D44D5-28A7-4EB3-B84B-8021FE3189F9}
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26} = {E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer_x86", "libwdi\installer_x86_2008.vcproj", "{9B1C561E-F95B-4849-A7AA-A4350E227C20}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer_x64", "libwdi\installer_x64_2008.vcproj", "{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig", "examples\libconfig\libconfig.vcproj", "{2945B0AC-AB99-483F-9FDC-CF76613E3034}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt", "examples\getopt\getopt.vcproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Debug|Win32.ActiveCfg = Debug|Win32
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Debug|Win32.Build.0 = Debug|Win32
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Debug|x64.ActiveCfg = Debug|x64
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Debug|x64.Build.0 = Debug|x64
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Release|Win32.ActiveCfg = Release|Win32
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Release|Win32.Build.0 = Release|Win32
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Release|x64.ActiveCfg = Release|x64
{9AA0E745-1A0A-4700-8ECB-6A6DE9DBF8B9}.Release|x64.Build.0 = Release|x64
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Debug|Win32.ActiveCfg = Debug|Win32
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Debug|Win32.Build.0 = Debug|Win32
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Debug|x64.ActiveCfg = Debug|x64
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Debug|x64.Build.0 = Debug|x64
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Release|Win32.ActiveCfg = Release|Win32
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Release|Win32.Build.0 = Release|Win32
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Release|x64.ActiveCfg = Release|x64
{792D44D5-28A7-4EB3-B84B-8021FE3189F9}.Release|x64.Build.0 = Release|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|Win32.ActiveCfg = Debug|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|Win32.Build.0 = Debug|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|x64.ActiveCfg = Debug|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|x64.Build.0 = Debug|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|Win32.ActiveCfg = Release|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|Win32.Build.0 = Release|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|x64.ActiveCfg = Release|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|x64.Build.0 = Release|x64
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|Win32.ActiveCfg = Debug|Win32
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|Win32.Build.0 = Debug|Win32
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|x64.ActiveCfg = Debug|x64
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|x64.Build.0 = Debug|x64
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Release|Win32.ActiveCfg = Release|Win32
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Release|Win32.Build.0 = Release|Win32
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Release|x64.ActiveCfg = Release|x64
{F7F7842F-2912-454E-ADF5-0B22987946E2}.Release|x64.Build.0 = Release|x64
{79275348-41A4-4D07-8990-4068C9594A2C}.Debug|Win32.ActiveCfg = Debug|Win32
{79275348-41A4-4D07-8990-4068C9594A2C}.Debug|x64.ActiveCfg = Debug|x64
{79275348-41A4-4D07-8990-4068C9594A2C}.Release|Win32.ActiveCfg = Release|Win32
{79275348-41A4-4D07-8990-4068C9594A2C}.Release|x64.ActiveCfg = Release|x64
{9B1C561E-F95B-4849-A7AA-A4350E227C20}.Debug|Win32.ActiveCfg = Debug|Win32
{9B1C561E-F95B-4849-A7AA-A4350E227C20}.Debug|Win32.Build.0 = Debug|Win32
{9B1C561E-F95B-4849-A7AA-A4350E227C20}.Debug|x64.ActiveCfg = Debug|Win32
{9B1C561E-F95B-4849-A7AA-A4350E227C20}.Release|Win32.ActiveCfg = Release|Win32
{9B1C561E-F95B-4849-A7AA-A4350E227C20}.Release|Win32.Build.0 = Release|Win32
{9B1C561E-F95B-4849-A7AA-A4350E227C20}.Release|x64.ActiveCfg = Release|Win32
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Debug|Win32.ActiveCfg = Debug|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Debug|Win32.Build.0 = Debug|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Debug|x64.ActiveCfg = Debug|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Debug|x64.Build.0 = Debug|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|Win32.ActiveCfg = Release|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|Win32.Build.0 = Release|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|x64.ActiveCfg = Release|x64
{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|x64.Build.0 = Release|x64
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Debug|Win32.ActiveCfg = Debug|Win32
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Debug|Win32.Build.0 = Debug|Win32
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Debug|x64.ActiveCfg = Debug|x64
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Debug|x64.Build.0 = Debug|x64
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Release|Win32.ActiveCfg = Release|Win32
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Release|Win32.Build.0 = Release|Win32
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Release|x64.ActiveCfg = Release|x64
{2945B0AC-AB99-483F-9FDC-CF76613E3034}.Release|x64.Build.0 = Release|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.Build.0 = Debug|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.ActiveCfg = Release|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.Build.0 = Release|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.ActiveCfg = Release|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,50 @@
/* config.h. Manual config for MSVC. */
#ifdef _MSC_VER
/* embed WinUSB driver files from the following DDK location */
#ifndef DDK_DIR
// #define DDK_DIR "E:/WinDDK/7600.16385.0"
#endif
/* embed libusb0 driver files from the following location */
#ifndef LIBUSB0_DIR
// #define LIBUSB0_DIR "D:/libusb-win32"
#endif
/* embed user defined driver files from the following location */
#if !defined(USER_DIR) && !defined(LIBUSB0_DIR) && !defined(DDK_DIR)
#define USER_DIR ""
#endif
/* DDK WDF coinstaller version (string) */
#define WDF_VER "01009"
/* 32 bit support */
//#define OPT_M32
/* 64 bit support */
//#define OPT_M64
/* embed IA64 driver files */
//#define OPT_IA64
#else // end of MSVC defaults
#endif
// MSVC and GCC defaults
#if defined(DBG) || defined(DEBUG) || defined(_DEBUG)
/* Debug message logging */
#define ENABLE_DEBUG_LOGGING
/* Debug message logging (toggable) */
#define INCLUDE_DEBUG_LOGGING
/* Message logging */
#define ENABLE_LOGGING 1
/* Output log message to a debug window/DebugView */
#define LOG_OUTPUT_DEBUGWINDOW
#endif
@@ -0,0 +1,299 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file was original part of the w64 mingw-runtime package.
*/
/*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* Modified for libusb/MSVC: Pete Batard <pbatard@gmail.com>
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Date: 2010-04-02
*/
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
/* 7.8 Format conversion of integer types <inttypes.h> */
#ifndef _INTTYPES_H_
#define _INTTYPES_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
/* 7.8.1 Macros for format specifiers
*
* MS runtime does not yet understand C9x standard "ll"
* length specifier. It appears to treat "ll" as "l".
* The non-standard I64 length specifier causes warning in GCC,
* but understood by MS runtime functions.
*/
/* fprintf macros for signed types */
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "I64d"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "d"
#define PRIdLEAST64 "I64d"
#define PRIdFAST8 "d"
#define PRIdFAST16 "d"
#define PRIdFAST32 "d"
#define PRIdFAST64 "I64d"
#define PRIdMAX "I64d"
#define PRIi8 "i"
#define PRIi16 "i"
#define PRIi32 "i"
#define PRIi64 "I64i"
#define PRIiLEAST8 "i"
#define PRIiLEAST16 "i"
#define PRIiLEAST32 "i"
#define PRIiLEAST64 "I64i"
#define PRIiFAST8 "i"
#define PRIiFAST16 "i"
#define PRIiFAST32 "i"
#define PRIiFAST64 "I64i"
#define PRIiMAX "I64i"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "o"
#define PRIo64 "I64o"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "o"
#define PRIoLEAST64 "I64o"
#define PRIoFAST8 "o"
#define PRIoFAST16 "o"
#define PRIoFAST32 "o"
#define PRIoFAST64 "I64o"
#define PRIoMAX "I64o"
/* fprintf macros for unsigned types */
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 "I64u"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "u"
#define PRIuLEAST64 "I64u"
#define PRIuFAST8 "u"
#define PRIuFAST16 "u"
#define PRIuFAST32 "u"
#define PRIuFAST64 "I64u"
#define PRIuMAX "I64u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIx64 "I64x"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "x"
#define PRIxLEAST64 "I64x"
#define PRIxFAST8 "x"
#define PRIxFAST16 "x"
#define PRIxFAST32 "x"
#define PRIxFAST64 "I64x"
#define PRIxMAX "I64x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIX64 "I64X"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "X"
#define PRIXLEAST64 "I64X"
#define PRIXFAST8 "X"
#define PRIXFAST16 "X"
#define PRIXFAST32 "X"
#define PRIXFAST64 "I64X"
#define PRIXMAX "I64X"
/*
* fscanf macros for signed int types
* NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
* (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
* no length identifiers
*/
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 "I64d"
#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 "I64d"
#define SCNdFAST16 "hd"
#define SCNdFAST32 "d"
#define SCNdFAST64 "I64d"
#define SCNdMAX "I64d"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 "I64i"
#define SCNiLEAST16 "hi"
#define SCNiLEAST32 "i"
#define SCNiLEAST64 "I64i"
#define SCNiFAST16 "hi"
#define SCNiFAST32 "i"
#define SCNiFAST64 "I64i"
#define SCNiMAX "I64i"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 "I64o"
#define SCNoLEAST16 "ho"
#define SCNoLEAST32 "o"
#define SCNoLEAST64 "I64o"
#define SCNoFAST16 "ho"
#define SCNoFAST32 "o"
#define SCNoFAST64 "I64o"
#define SCNoMAX "I64o"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 "I64x"
#define SCNxLEAST16 "hx"
#define SCNxLEAST32 "x"
#define SCNxLEAST64 "I64x"
#define SCNxFAST16 "hx"
#define SCNxFAST32 "x"
#define SCNxFAST64 "I64x"
#define SCNxMAX "I64x"
/* fscanf macros for unsigned int types */
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 "I64u"
#define SCNuLEAST16 "hu"
#define SCNuLEAST32 "u"
#define SCNuLEAST64 "I64u"
#define SCNuFAST16 "hu"
#define SCNuFAST32 "u"
#define SCNuFAST64 "I64u"
#define SCNuMAX "I64u"
#ifdef _WIN64
#define PRIdPTR "I64d"
#define PRIiPTR "I64i"
#define PRIoPTR "I64o"
#define PRIuPTR "I64u"
#define PRIxPTR "I64x"
#define PRIXPTR "I64X"
#define SCNdPTR "I64d"
#define SCNiPTR "I64i"
#define SCNoPTR "I64o"
#define SCNxPTR "I64x"
#define SCNuPTR "I64u"
#else
#define PRIdPTR "d"
#define PRIiPTR "i"
#define PRIoPTR "o"
#define PRIuPTR "u"
#define PRIxPTR "x"
#define PRIXPTR "X"
#define SCNdPTR "d"
#define SCNiPTR "i"
#define SCNoPTR "o"
#define SCNxPTR "x"
#define SCNuPTR "u"
#endif
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/*
* no length modifier for char types prior to C9x
* MS runtime scanf appears to treat "hh" as "h"
*/
/* signed char */
#define SCNd8 "hhd"
#define SCNdLEAST8 "hhd"
#define SCNdFAST8 "hhd"
#define SCNi8 "hhi"
#define SCNiLEAST8 "hhi"
#define SCNiFAST8 "hhi"
#define SCNo8 "hho"
#define SCNoLEAST8 "hho"
#define SCNoFAST8 "hho"
#define SCNx8 "hhx"
#define SCNxLEAST8 "hhx"
#define SCNxFAST8 "hhx"
/* unsigned char */
#define SCNu8 "hhu"
#define SCNuLEAST8 "hhu"
#define SCNuFAST8 "hhu"
#endif /* __STDC_VERSION__ >= 199901 */
#endif /* !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) */
#ifdef __cplusplus
}
#endif
#endif /* ndef _INTTYPES_H */
@@ -0,0 +1,273 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file was originally part of the w64 mingw-runtime package.
*/
/* ISO C9x 7.18 Integer types <stdint.h>
* Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
* Modified for libusb/MSVC: Pete Batard <pbatard@gmail.com>
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Date: 2010-04-02
*/
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
#ifndef _STDINT_H
#define _STDINT_H
/* from stddef.h and _mingw.h */
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef int ssize_t;
#endif /* _WIN64 */
#endif /* _SSIZE_T_DEFINED */
#ifndef _INTPTR_T_DEFINED
#define _INTPTR_T_DEFINED
#ifndef __intptr_t_defined
#define __intptr_t_defined
#undef intptr_t
#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef int intptr_t;
#endif /* _WIN64 */
#endif /* __intptr_t_defined */
#endif /* _INTPTR_T_DEFINED */
#ifndef _UINTPTR_T_DEFINED
#define _UINTPTR_T_DEFINED
#ifndef __uintptr_t_defined
#define __uintptr_t_defined
#undef uintptr_t
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef unsigned int uintptr_t;
#endif /* _WIN64 */
#endif /* __uintptr_t_defined */
#endif /* _UINTPTR_T_DEFINED */
#ifndef _PTRDIFF_T_DEFINED
#define _PTRDIFF_T_DEFINED
#ifndef _PTRDIFF_T_
#define _PTRDIFF_T_
#undef ptrdiff_t
#ifdef _WIN64
typedef __int64 ptrdiff_t;
#else
typedef int ptrdiff_t;
#endif /* _WIN64 */
#endif /* _PTRDIFF_T_ */
#endif /* _PTRDIFF_T_DEFINED */
#ifndef _WCHAR_T_DEFINED
#define _WCHAR_T_DEFINED
#ifndef __cplusplus
typedef unsigned short wchar_t;
#endif /* C++ */
#endif /* _WCHAR_T_DEFINED */
#ifndef _WCTYPE_T_DEFINED
#define _WCTYPE_T_DEFINED
#ifndef _WINT_T
#define _WINT_T
typedef unsigned short wint_t;
typedef unsigned short wctype_t;
#endif /* _WINT_T */
#endif /* _WCTYPE_T_DEFINED */
/* 7.18.1.1 Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
/* 7.18.1.2 Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_least32_t;
typedef unsigned uint_least32_t;
typedef long long int_least64_t;
typedef unsigned long long uint_least64_t;
/* 7.18.1.3 Fastest minimum-width integer types
* Not actually guaranteed to be fastest for all purposes
* Here we use the exact-width types for 8 and 16-bit ints.
*/
typedef signed char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short int_fast16_t;
typedef unsigned short uint_fast16_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
typedef long long int_fast64_t;
typedef unsigned long long uint_fast64_t;
/* 7.18.1.5 Greatest-width integer types */
typedef long long intmax_t;
typedef unsigned long long uintmax_t;
/* 7.18.2 Limits of specified-width integer types */
#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS)
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 0xffffffffU /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.3 Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding
object pointers */
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
/* 7.18.3 Limits of other integer types */
#ifdef _WIN64
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#endif
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#ifndef SIZE_MAX
#ifdef _WIN64
#define SIZE_MAX UINT64_MAX
#else
#define SIZE_MAX UINT32_MAX
#endif
#endif
#ifndef WCHAR_MIN /* also in wchar.h */
#define WCHAR_MIN 0U
#define WCHAR_MAX 0xffffU
#endif
/*
* wint_t is unsigned short for compatibility with MS runtime
*/
#define WINT_MIN 0U
#define WINT_MAX 0xffffU
#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */
/* 7.18.4 Macros for integer constants */
#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS)
/* 7.18.4.1 Macros for minimum-width integer constants
Accoding to Douglas Gwyn <gwyn@arl.mil>:
"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
9899:1999 as initially published, the expansion was required
to be an integer constant of precisely matching type, which
is impossible to accomplish for the shorter types on most
platforms, because C99 provides no standard way to designate
an integer constant with width less than that of type int.
TC1 changed this to require just an integer constant
*expression* with *promoted* type."
The trick used here is from Clive D W Feather.
*/
#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
/* The 'trick' doesn't work in C89 for long long because, without
suffix, (val) will be evaluated as int, not intmax_t */
#define INT64_C(val) val##LL
#define UINT8_C(val) (val)
#define UINT16_C(val) (val)
#define UINT32_C(val) (val##U)
#define UINT64_C(val) val##ULL
/* 7.18.4.2 Macros for greatest-width integer constants */
#define INTMAX_C(val) val##LL
#define UINTMAX_C(val) val##ULL
#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */
#endif