/*

Copyright (c) 2003  Microsoft Corporation

File name:

    tokyodemo.h
   
*/

#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
#include <time.h>
#include <tchar.h>

typedef struct _TREE_NODE {
    LONG Value;
    struct _TREE_NODE *Left, *Right;
} TREE_NODE, *PTREE_NODE;

typedef struct _VALUE_RANGE {
    LONG Low, High;
} VALUE_RANGE, *PVALUE_RANGE;

typedef struct _PAGE_FAULT_INFO {
    HANDLE Process;
    HANDLE Thread;
    PVOID FaultAddress;
} PAGE_FAULT_INFO, *PPAGE_FAULT_INFO;

typedef BOOL (*TOK_PAGE_FAULT_HANDLER_FN)(IN PPAGE_FAULT_INFO PageFaultInfo);

//
// This executable should be kept in the directory from which the user's executable is launched.
//

#define TOKYO_FAULT_PROCESS _T("tokyo_vm.exe")

//
// Returns the time in seconds since the machine booted. This is a high precision value and
// differences in readings can be used to measure duration of segments of code.
//

double
TokGetTime(
    VOID
    );

//
// Simulates CPU-bound for the time duration indicated (in seconds).
//

VOID 
TokConsumeCPU(
    double RunTime
    );

//
// Generates a tree containing the indicated number of unique elements, each in the range
// indicated. Returns NULL on failure.
//

PTREE_NODE
TokGenerateTree(
    IN DWORD NumElements,
    IN PVALUE_RANGE Range
    );

//
// Releases the memory associated with a tree previously created by TokGenerateTree.
//

VOID
TokDeleteTree(
    IN PTREE_NODE Root
    );

//
// Prints the in-order traversal of the passed tree.
//

VOID
TokPrintTree(
    IN PTREE_NODE Root
    );

//
// Returns a buffer of code that must be later released by TokReleaseCodeBuffer. Simulates
// reading a code segment from a file.
//

PVOID
TokGetCodeBuffer(
    OUT PDWORD NumCodeBytes
    );

//
// Releases the buffer previously allocated by TokGetCodeBuffer.
//

VOID
TokReleaseCodeBuffer(
    IN PVOID Buffer
    );

//
// Launches the TOKYO_FAULT_PROCESS, passing it the indicated parameter array. For each
// page fault incurred by the launched process, the passed handler is invoked. This function
// returns when the launched process exits. Returns an error code to indicate the result.
//

DWORD
TokOSLaunchFaultingProcess(
    IN TOK_PAGE_FAULT_HANDLER_FN Handler,
    IN TCHAR *argv[]
    );

//
//  Creates a process w/o registering with csrss, and with a custom 
//  provided exception port
//

HANDLE
TokCreateLightProcess (
    PWCHAR ImageFileName,
    PWCHAR LibraryPath,
    PWCHAR CurrentDirectory,
    PWCHAR CommandLine,
    HANDLE ExceptionPort
    );

#define TOK_LPC_REQUEST             1
#define TOK_LPC_REPLY               2
#define TOK_LPC_DATAGRAM            3
#define TOK_LPC_LOST_REPLY          4
#define TOK_LPC_PORT_CLOSED         5
#define TOK_LPC_CLIENT_DIED         6
#define TOK_LPC_EXCEPTION           7
#define TOK_LPC_DEBUG_EVENT         8
#define TOK_LPC_ERROR_EVENT         9
#define TOK_LPC_CONNECTION_REQUEST 10

typedef struct _TOK_PORT_MESSAGE {
    unsigned short DataLength;
    unsigned short TotalLength;
    unsigned short Type;
    unsigned short DataInfoOffset;
    ULONG_PTR ClientProcessId;
    ULONG_PTR ClientThreadId;
    ULONG MessageId;
    ULONG CallbackId;              
//  UCHAR Data[];
} TOK_PORT_MESSAGE, *PTOK_PORT_MESSAGE;

HANDLE
TokCreatePort (
    PWCHAR PortName,
    ULONG MaxMessageSize
    );


HANDLE
TokConnectPort (
    PWCHAR PortName
    );

HANDLE
TokAcceptConnection (
    PTOK_PORT_MESSAGE ConnectionMessage,
    BOOLEAN AcceptConnection,
    PVOID PortContext
    );

LONG
TokRequestWaitReplyMessage (
    HANDLE PortHandle,
    PTOK_PORT_MESSAGE RequestMessage,
    PTOK_PORT_MESSAGE ReplyBuffer
    );

LONG
TokReplyWaitReceive (
    HANDLE PortHandle,
    PTOK_PORT_MESSAGE ReplyMessage,  // optional
    PTOK_PORT_MESSAGE ReceiveMessage,  // optional
    PVOID * PortContext  // optional
    );


