From ReactOS Wiki
Revision as of 08:29, 26 June 2005 by Alex Ionescu (talk | contribs) (How is the NDK Licensed?)
Jump to: navigation, search

Native Development Kit Guidelines

This document serves as a brief introduction to the NDK, what should go in it, what shouldn't, and how the information is organized at the file level, as well as how the syntax and formatting is done at the source level.

What is the NDK?

The NDK, or Native Development Kit, is the brainchild of Alex Ionescu, allowing Windows and ReactOS developers alike to have access to a wealth of undocumented kernel and native structures and function prototypes.

Without the NDK, Windows developers are forced to define their own "undoct.h" headers in which they copy/paste information found online, which may or may not be valid and updated. For native types, this is even harder, as sometimes the information is present in the DDK or IFS, but cannot be used in a user-mode application, nor can it be copy-pasted. The developer must re-write all the definitions he needs.

Without the NDK, ReactOS developers are forced to use a system of up to 3 kinds of duplicated headers (sometimes four) containing identical, similar, or worse, different information. Differences between these headers create compile-time problems, and fixing one header set without updating the other usually causes brekage in applications compiled with "W32API" headers versus applications compiled with "ddk" headers vesus applications compiled with "ntos" headers.

The NDK provides a unified header set for development of:

  • User mode applications which use native functions (include windows.h and the user-mode NDK)
  • Native applications (include the user-mode NDK)
  • Kernel-mode drivers which use undocumented kernel functions (include ddk and/or ifs and kernel-mode NDK)

What goes in the NDK?

Because the NDK is a triple-mode header set, care must be taken to avoid collisions. The following information should go in the NDK:

  • Kernel-Mode API Function Prototypes or Types which are undocumented in the DDK or IFS. Sorry, but if the information is documented in the IFS but not the DDK, you must include the IFS in your program (thankfully we provide free IFS Headers). For Types which vary according to version information, always include the most recent version. If older versions are needed, use a compile-time macro to read the build environment (target version) and choose the correct structure.
  • Native (RTL, DBG, PFX, NT/ZW) API Function Prototypes or Types which are undocumented in the DDK, IFS or Windows Headers.
    • If the Type is documented in the DDK or IFS, you must add the definition to umtypes.h. This special header allows the shared parts of the NDK to be used from User-Mode applications and defines things like UNICODE_STRING, the various NTSTATUS codes, IRP codes, and all other Native Types which are not in the DDK or IFS.
    • Sometimes, but rarely, you will find Native Types which are actually Win32 types, defined in Windows headers but not in DDK/IFS. In that case, you must add the definition to the special protected block (ex:#ifndef _WINBASE_H) so that it will be skipped by user-mode applications.

What should not go in the NDK?

  • Do not add documented information in the NDK unless it must be accessible from user-mode (which cannot include DDK or IFS), see above guidelines.
  • Do not add Native ReactOS Specific information anywhere.
  • Do not add Private ReactOS function or types.
  • Do not add User-Mode undocumented functions (like shell32, etc).
    • However, if the function is inside ntdll, you must add it to "umfuncs.h"

How is the NDK organized?

  • The NDK is organized in a main folder (include/ndk) with arch-specific subfolders (ex: include/ndk/i386).
  • The NDK is structured by NT Subsystem Component (ex: ex, ps, rtl, etc).
  • The NDK can either be included on-demand (#include <ndk/xxxxx.h>) or globally (#include <ndk/ntndk.h>). The latter is recommended.
  • The NDK is structured by function and type. Every Subsystem Component has an associated "xxfuncs.h" and "xxtypes.h" header, where "xx" is the Subsystem (ex: iofuncs.h, iotypes.h)
  • The NDK has a special file called "umtypes.h" which exports to User-Mode or Native-Mode Applications the documented types in the DDK and/or IFS which are not normally exposed to them.
  • The NDK also includes a file called "umfuncs.h" which exports to User-Mode or Native-Mode Applications undocumented functions which can only be accessed from ntdll.dll.

What is the formatting syntax in the NDK?

Types must be defined as follows:

typedef struct _TYPENAME
    PMEMBER_TYPE Member1;
    MEMBER_TYPE1 Member2;
    struct _TYPENAME *SelfMember;
            UCHAR Member3:4;
            UCHAR Member4:4;
        UCHAR Member5;
    MEMVER_TYPE2 Member6;

Prototypes as follows:

    PARAM_TYPE Param1,
    PARAM_TYPE Param2

Similalry, function types:

    PARAM_TYPE Param1,
    PARAM_TYPE Param2

How is the NDK Licensed?

  • A file called COPYING at the root of the NDK directory will describe the NDK's license. This license will be OSI-Approved and will either be the w32api license, the libzlib/libpng license, the LGPL license or the BSD 2.0 License. Nevertheless, the following licensing requirements will probably be part of any license chosen:
    • The right to use the NDK in any commercial project without limits others then the ones below.
    • The right to make any number of derivatives of the NDK
      • However, you may not call these derivatives "NDK" anymore and must dissociate the author from them except for copyright (see below)
        • Nevertheless, any derivative or modified version must reference the original work and author. (ie: You cannot call your derivative work 'NDK Headers 2.0, by Alex Ionescu'. They could be called, for example 'Windows Native Headers 2.0, by John Smith' and must contain a clause similar to "Based on NDK Headers 1.0, by Alex Ionescu". The same principle applies for the copyright text.
      • Additionally, it is appreciated, but not required to send any modifications back to the author. This will assure that the derivative version might re-convert into an official version.
        • You understand that by not submitting your changes, your derivative work will become 'out of sync', at which point other developers/testers will be forced to use your distribution if your application requires it. You understand that, at any time, the official NDK distribution could be manually updated to contain your changes, or might contain changes which are incompatible with yours, and that, at said point, your NDK distribution might become incompatible.
      • You must keep the same rights that this license grants, and you may not add any further limitations to it (in other words, the unchanged COPYRIGHT file must be present along with your distribution). This implies that you may not prohibit the author from merging your changes in the official NDK, even if you do not submit them.
    • The right to re-distribute the NDK, or any derivative version of it, using any medium, technology and distribution method, including commercial.
      • However, the author retains the original copyright.
      • You must keep the same rights that this license grants, and you may not add any further limitations to it (in other words, the unchanged COPYRIGHT file must be present along with your distribution).
    • There is no guarantee, warranty or support offerred for using the NDK. The author is not responsible for any losses or damages.
    • The author retains all copyright to the NDK.

How do I use the NDK?

  • User Mode Application requiring Native Types:
 #include <windows.h>      /* Declare Windows Headers like you normally would */
 #DEFINE NTOS_MODE_USER    /* Tell the NDK that you are User Mode */
 #include <ndk/ntndk.h>    /* Declare the NDK Headers */
  • Native Mode Application:
 #DEFINE NTOS_MODE_USER    /* Tell the NDK that you are User Mode */
 #include <ndk/ntndk.h>    /* Declare the NDK Headers */
  • Kernel Mode Driver:
 #include <ddk/ntddk.h>    /* Declare DDK Headers like you normally would */
 #include <ndk/ntndk.h>    /* Declare the NDK Headers */

Some caveats

  • FIXMEs: There are still a large number of FIXMEs inside the NDK until it is ready for a 1.0 release. These have been documented into a file called FIXME at the root directory of the NDK. The goal is for all priority 1-4 bugs to be fixed before 0.3.0 in order for NDK 1.0 to be released publically.
  • winternl.h: This header, part of the PSDK, was released by Microsoft as part of one of the government lawsuits against it, and documentes a certain (minimal) part of the Native API and/or types. Unforunately, Microsoft decided to hack the Native Types and to define them incorrectly, replacing real members by "reserved" ones. As such, you 'cannot include winternl.h in any project that uses the NDK. Note however, that the NDK fully replaces it and retains compatibility with any project that used it.
  • pstypes.h: This header is a "dual-mode" header, meaning that it needs to be accessible from User-Mode, yet exports Kernel-Mode types as well; this is because it must define structures like the TEB or PEB as well as ETHREAD and EPROCESS. As such, the file is split in two and protected by the NTOS_MODE_USER definition. Please keep this in mind when adding a new Proces Manager type.
  • DDK/IFS Compatibility: Although one of its main goals, the NDK has not yet been targetted and/or tested with the official Microsoft Headers. However, a lot of work has been done to support this, and it should be a possibility soon after 1.0