= lfanew

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Macros to work around AsciiDoc lossage. :-|
:plus: +
:lowline: _
:or: |
:nbsp:  
:bcmt: /*{nbsp}
:ecmt: {nbsp}*/
:bopt: [
:eopt: ]

https://ci.appveyor.com/project/tkchia/lfanew/branch/main[image:https://ci.appveyor.com/api/projects/status/glvafsajsnflh3rn/branch/main["AppVeyor build status"]]

`lfanew` comprises

* a tool to manipulate fat binary programs wrapped inside MS-DOS `MZ` files;
* plus a simple C code library for working with binary files, including MS-DOS executables.

== Tool

:fn-pietrek-19: footnote:pietrek-19[M. Pietrek.  Inside Windows: an in-depth look into the Win32 Portable Executable file format.  MSDN Magazine, Feb 2002.  https://learn.microsoft.com/en-us/archive/msdn-magazine/2002/february/inside-windows-win32-portable-executable-file-format-in-detail.]
:fn-microsoft-23: footnote:microsoft-23[Microsoft Corporation.  PE Format.  Microsoft Learn, 24 Mar 2023.  https://learn.microsoft.com/en-us/windows/win32/debug/pe-format.  Archived on 26 Jul 2023 at https://web.archive.org/web/20230726221442/https://learn.microsoft.com/en-us/windows/win32/debug/pe-format.]

Usage:

* ``lfanew`` [``-k``] ``-o`` __out-stub-file__ __in-stub-file__
* ``lfanew -S`` [``-kp``] ``-o`` __out-fat-file__ __in-payload-file__ __in-stub-file__
* ``lfanew -U`` [``-kp``] ``-o`` __out-payload-file__ __in-fat-file__

Operating modes:

* On default, `lfanew` adds a `.e_lfanew` header field{fn-pietrek-19} to an old-style `MZ` executable program, so that the program can potentially be used as an MS-DOS loader stub for a modern "new executable" format.
* `-S` ("stubify"): tells `lfanew` to create a fat binary by combining an `MZ` stub with a "new executable" payload.
* `-U` ("unstubify"): tells `lfanew` to extract the "new executable" payload contained inside a fat binary, removing any `MZ` stub.

Options:

* `-k` ("keep"): says to keep the output file in case of an error, rather than delete it.
* `-p` ("pages"): for `-S` or `-U`, says to derive the stub size from `.e_cp` and `.e_cblp`, rather than from `.e_lfanew`.

`lfanew` can add a stub to a Microsoft Portable Executable (`PE`){fn-microsoft-23} payload, if there is enough RVA space before the `PE` sections to accommodate the stub (and `PE` headers).  You will likely need to unstubify a `PE` program before attaching it to a different stub.

== Code library

=== Legend

:fn-ieee-08: footnote:ieee-08[Institute of Electrical and Electronics Engineers, and The Open Group.  IEEE Std 1003.1™-2008,  2008. https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/.]

[cols=">1,9"]
|===
| Compat. | Meaning

|     P08 | Part of the POSIX.1-2008{fn-ieee-08} standard.
|       X | `lfanew`-specific extension.
|===

[cols=">1,9"]
|===
| Avail. | Meaning

|      = | Facility is available for all host platforms.
|    (=) | Facility is available if the host platform does not already define this facility itself.
|     64 | Facility is available only if the host C compiler directly support 64-bit integers (``uint64_t`` etc.).
|===

=== Types

[cols=">1,>1,<3,<3"]
|===
|Compat. |Avail. <| Type <| Notes

2+|           2+<a| **``▗▚▚▚▚ <nexgen/mzendian.h> ▞▞▞▞▖``**

			* **This header defines types and routines for accessing unaligned little endian binary data in a type-checked manner.**
			* **``<nexgen/mzendian.h>`` also includes ``<stdint.h>``.**

|      X |      = | ``uint_le16_t`` .3+| Unaligned 16-, 32-, or 64-bit little endian binary numeral.  These types can be used directly inside a ``struct`` or ``union`` corresponding to a binary file structure, but should otherwise be treated as opaque.
|      X |      = | ``uint_le32_t``
|      X |      = | ``uint_le64_t``
4+|
2+|            2+<| **``▗▚▚▚▚ <nexgen/mzhdr.h> ▞▞▞▞▖``**
|      X |      = | ``mz_hdr_t`` | ``MZ`` structure{fn-pietrek-19} at the beginning of an MS-DOS or Windows program.
|===

=== Functions

[cols=">1,>1,<3,<3"]
|===
|Compat. |Avail. <| Function <| Notes

2+|           2+<a| **``▗▚▚▚▚ <lfanew/dirent.h> ▞▞▞▞▖``**
|    P08 |    (=) | ``scandir (``*__path__``,`` *__names__``,`` *__filt__``,`` *__comp__``);`` a|
			* Scans the directory given by __path__, filters them with __filt__, then returns a ``malloc``'d list of directory entries in *__names__ sorted with the comparator __comp__.
			* (POSIX places this function in ``<dirent.h>``.)
4+|
2+|            2+<| **``▗▚▚▚▚ <lfanew/io.h> ▞▞▞▞▖``**
|      X |      = | ``_binmode (``__handle__``);`` a|
			* Sets the POSIX-style file __handle__ to do untranslated (binary) I/O — so that ``read`` and ``write`` calls with the __handle__ will not translate between LF and CRLF, nor specially interpret bytes that look like end-of-file indicators.
			* Upon an error, this function returns -1 and sets ``errno``.
4+|
2+|            2+<| **``▗▚▚▚▚ <nexgen/mzendian.h> ▞▞▞▞▖``**
|      X |      = | ``uint_le16_t hle16 (uint16_t``{nbsp}__x__``);`` .3+| Converts __x__ from host byte order to little endian.
|      X |      = | ``uint_le32_t hle32 (uint32_t``{nbsp}__x__``);``
|      X |     64 | ``uint_le64_t hle64 (uint64_t``{nbsp}__x__``);``
|      X |      = | ``uint16_t leh16 (uint_le16_t``{nbsp}__x__``);`` .2+| Converts __x__ from little endian to host byte order.
|      X |      = | ``uint32_t leh32 (uint_le32_t``{nbsp}__x__``);``
|      X |      = | ``uint16_t leh32hi (uint_le32_t``{nbsp}__x__``);`` .2+| Converts __x__ from little endian to host byte order, and returns the high or low 16-bit half respectively.
|      X |      = | ``uint16_t leh32lo (uint_le32_t``{nbsp}__x__``);``
|      X |     64 | ``uint64_t leh64 (uint_le64_t``{nbsp}__x__``);`` | Converts __x__ from little endian to host byte order.
|      X |      = | ``uint32_t leh64hi (uint_le64_t``{nbsp}__x__``);`` .2+| Converts __x__ from little endian to host byte order, and returns the high or low 32-bit half respectively.
|      X |      = | ``uint32_t leh64lo (uint_le64_t``{nbsp}__x__``);``
|===
