/*
 * winnt4.h
 *
 * Definitions only used in Windows NT 4.0 and earlier versions
 *
 * This file is part of the w32api package.
 *
 * Contributors:
 *   Created by Casper S. Hornstrup <chorns@users.sourceforge.net>
 *
 * THIS SOFTWARE IS NOT COPYRIGHTED
 *
 * 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.
 *
 */

#ifndef __WINNT4_H
#define __WINNT4_H

#if __GNUC__ >=3
#pragma GCC system_header
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _ZONE_SEGMENT_HEADER {
  SINGLE_LIST_ENTRY  SegmentList;
  PVOID  Reserved;
} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;

typedef struct _ZONE_HEADER {
  SINGLE_LIST_ENTRY  FreeList;
  SINGLE_LIST_ENTRY  SegmentList;
  ULONG  BlockSize;
  ULONG  TotalSegmentSize;
} ZONE_HEADER, *PZONE_HEADER;

static __inline PVOID
ExAllocateFromZone(
  IN PZONE_HEADER  Zone)
{
  if (Zone->FreeList.Next)
    Zone->FreeList.Next = Zone->FreeList.Next->Next;
  return (PVOID) Zone->FreeList.Next;
}

NTOSAPI
NTSTATUS
DDKAPI
ExExtendZone(
  IN PZONE_HEADER  Zone,
  IN PVOID  Segment,
  IN ULONG  SegmentSize);

static __inline PVOID
ExFreeToZone(
  IN PZONE_HEADER  Zone,
  IN PVOID  Block)
{
  ((PSINGLE_LIST_ENTRY) Block)->Next = Zone->FreeList.Next;
  Zone->FreeList.Next = ((PSINGLE_LIST_ENTRY) Block);
  return ((PSINGLE_LIST_ENTRY) Block)->Next;
}

NTOSAPI
NTSTATUS
DDKAPI
ExInitializeZone(
  IN PZONE_HEADER  Zone,
  IN ULONG  BlockSize,
  IN PVOID  InitialSegment,
  IN ULONG  InitialSegmentSize);

/*
 * PVOID
 * ExInterlockedAllocateFromZone(
 *   IN PZONE_HEADER  Zone,
 *   IN PKSPIN_LOCK  Lock)
 */
#define ExInterlockedAllocateFromZone(Zone, \
                              Lock) \
  ((PVOID) ExInterlockedPopEntryList(&Zone->FreeList, Lock))

NTOSAPI
NTSTATUS
DDKAPI
ExInterlockedExtendZone(
  IN PZONE_HEADER  Zone,
  IN PVOID  Segment,
  IN ULONG  SegmentSize,
  IN PKSPIN_LOCK  Lock);

NTOSAPI
PVOID
DDKAPI
ExInterlockedFreeToZone(
  IN PZONE_HEADER  Zone,
  IN PVOID  Block,
  IN PKSPIN_LOCK  Lock);

/*
 * VOID
 * ExInitializeWorkItem(
 *   IN PWORK_QUEUE_ITEM  Item,
 *   IN PWORKER_THREAD_ROUTINE  Routine,
 *   IN PVOID  Context)
 */
#define ExInitializeWorkItem(Item, \
                             Routine, \
                             Context) \
{ \
  (Item)->WorkerRoutine = Routine; \
  (Item)->Parameter = Context; \
  (Item)->List.Flink = NULL; \
}

/*
 * BOOLEAN
 * ExIsFullZone(
 *  IN PZONE_HEADER  Zone)
 */
#define ExIsFullZone(Zone) \
  ((Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY) NULL)

NTOSAPI
VOID
DDKAPI
ExQueueWorkItem(
  IN PWORK_QUEUE_ITEM  WorkItem,
  IN WORK_QUEUE_TYPE  QueueType);

NTOSAPI
BOOLEAN
DDKAPI
ExIsObjectInFirstZoneSegment(
  IN PZONE_HEADER  Zone,
  IN PVOID  Object);

NTOSAPI
VOID
DDKAPI
ExReleaseResource(
  IN PERESOURCE  Resource);

#define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite
#define ExAcquireResourceShared ExAcquireResourceSharedLite
#define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite
#define ExDeleteResource ExDeleteResourceLite
#define ExInitializeResource ExInitializeResourceLite
#define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite
#define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite
#define ExIsResourceAcquired ExIsResourceAcquiredSharedLite
#define ExReleaseResourceForThread ExReleaseResourceForThreadLite

NTOSAPI
INTERLOCKED_RESULT
DDKAPI
ExInterlockedDecrementLong(
  IN PLONG  Addend,
  IN PKSPIN_LOCK  Lock);

NTOSAPI
ULONG
DDKAPI
ExInterlockedExchangeUlong(
  IN PULONG  Target,
  IN ULONG  Value,
  IN PKSPIN_LOCK  Lock);

NTOSAPI
INTERLOCKED_RESULT
DDKAPI
ExInterlockedIncrementLong(
  IN PLONG  Addend,
  IN PKSPIN_LOCK  Lock);

NTOSAPI
PVOID
DDKAPI
HalAllocateCommonBuffer(
  IN PADAPTER_OBJECT  AdapterObject,
  IN ULONG  Length,
  OUT PPHYSICAL_ADDRESS  LogicalAddress,
  IN BOOLEAN  CacheEnabled);

NTOSAPI
NTSTATUS
DDKAPI
HalAssignSlotResources(
  IN PUNICODE_STRING  RegistryPath,
  IN PUNICODE_STRING  DriverClassName,
  IN PDRIVER_OBJECT  DriverObject,
  IN PDEVICE_OBJECT  DeviceObject,
  IN INTERFACE_TYPE  BusType,
  IN ULONG  BusNumber,
  IN ULONG  SlotNumber,
  IN OUT PCM_RESOURCE_LIST  *AllocatedResources);

NTOSAPI
VOID
DDKAPI
HalFreeCommonBuffer(
  IN PADAPTER_OBJECT  AdapterObject,
  IN ULONG  Length,
  IN PHYSICAL_ADDRESS  LogicalAddress,
  IN PVOID  VirtualAddress,
  IN BOOLEAN  CacheEnabled);

NTOSAPI
PADAPTER_OBJECT
DDKAPI
HalGetAdapter(
  IN PDEVICE_DESCRIPTION  DeviceDescription,
  IN OUT PULONG  NumberOfMapRegisters);

NTOSAPI
ULONG
DDKAPI
HalGetBusData(
  IN BUS_DATA_TYPE  BusDataType,
  IN ULONG  BusNumber,
  IN ULONG  SlotNumber,
  IN PVOID  Buffer,
  IN ULONG  Length);

NTOSAPI
ULONG
DDKAPI
HalGetBusDataByOffset(
  IN BUS_DATA_TYPE  BusDataType,
  IN ULONG  BusNumber,
  IN ULONG  SlotNumber,
  IN PVOID  Buffer,
  IN ULONG  Offset,
  IN ULONG  Length);

NTOSAPI
ULONG
DDKAPI
HalGetDmaAlignmentRequirement( 
  VOID);

NTOSAPI
ULONG
DDKAPI
HalGetInterruptVector(
  IN INTERFACE_TYPE  InterfaceType,
  IN ULONG  BusNumber,
  IN ULONG  BusInterruptLevel,
  IN ULONG  BusInterruptVector,
  OUT PKIRQL  Irql,
  OUT PKAFFINITY  Affinity);

NTOSAPI
ULONG
DDKAPI
HalReadDmaCounter(
  IN PADAPTER_OBJECT  AdapterObject);

NTOSAPI
ULONG
DDKAPI
HalSetBusData(
  IN BUS_DATA_TYPE  BusDataType,
  IN ULONG  BusNumber,
  IN ULONG  SlotNumber,
  IN PVOID  Buffer,
  IN ULONG  Length);

NTOSAPI
ULONG
DDKAPI
HalSetBusDataByOffset(
  IN BUS_DATA_TYPE  BusDataType,
  IN ULONG  BusNumber,
  IN ULONG  SlotNumber,
  IN PVOID  Buffer,
  IN ULONG  Offset,
  IN ULONG  Length);

NTOSAPI
BOOLEAN
DDKAPI
HalTranslateBusAddress(
  IN INTERFACE_TYPE  InterfaceType,
  IN ULONG  BusNumber,
  IN PHYSICAL_ADDRESS  BusAddress,
  IN OUT PULONG  AddressSpace,
  OUT PPHYSICAL_ADDRESS  TranslatedAddress);

NTOSAPI
NTSTATUS
DDKAPI
IoAllocateAdapterChannel(
  IN PADAPTER_OBJECT  AdapterObject,
  IN PDEVICE_OBJECT  DeviceObject,
  IN ULONG  NumberOfMapRegisters,
  IN PDRIVER_CONTROL  ExecutionRoutine,
  IN PVOID  Context);

NTOSAPI
NTSTATUS
DDKAPI
IoAssignResources(
  IN PUNICODE_STRING  RegistryPath,
  IN PUNICODE_STRING  DriverClassName  OPTIONAL,
  IN PDRIVER_OBJECT  DriverObject,
  IN PDEVICE_OBJECT  DeviceObject  OPTIONAL,
  IN PIO_RESOURCE_REQUIREMENTS_LIST  RequestedResources,
  IN OUT PCM_RESOURCE_LIST  *AllocatedResources);

NTOSAPI
NTSTATUS
DDKAPI
IoAttachDeviceByPointer(
  IN PDEVICE_OBJECT  SourceDevice,
  IN PDEVICE_OBJECT  TargetDevice);

NTOSAPI
BOOLEAN
DDKAPI
IoFlushAdapterBuffers(
  IN PADAPTER_OBJECT  AdapterObject,
  IN PMDL  Mdl,
  IN PVOID  MapRegisterBase,
  IN PVOID  CurrentVa,
  IN ULONG  Length,
  IN BOOLEAN  WriteToDevice);

NTOSAPI
VOID
DDKAPI
IoFreeAdapterChannel(
  IN PADAPTER_OBJECT  AdapterObject);

NTOSAPI
VOID
DDKAPI
IoFreeMapRegisters(
  IN PADAPTER_OBJECT  AdapterObject,
  IN PVOID  MapRegisterBase,
  IN ULONG  NumberOfMapRegisters);

NTOSAPI
PHYSICAL_ADDRESS
DDKAPI
IoMapTransfer(
  IN PADAPTER_OBJECT  AdapterObject,
  IN PMDL  Mdl,
  IN PVOID  MapRegisterBase,
  IN PVOID  CurrentVa,
  IN OUT PULONG  Length,
  IN BOOLEAN  WriteToDevice);

NTOSAPI
PMDL
DDKAPI
MmCreateMdl(
  IN PMDL  MemoryDescriptorList  OPTIONAL,
  IN PVOID  Base,
  IN SIZE_T  Length);

NTOSAPI
BOOLEAN
DDKAPI
MmIsNonPagedSystemAddressValid(
  IN PVOID  VirtualAddress);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlEnlargedIntegerMultiply(
  IN LONG  Multiplicand,
  IN LONG  Multiplier);

NTOSAPI
ULONG
DDKAPI
RtlEnlargedUnsignedDivide(
  IN ULARGE_INTEGER  Dividend,
  IN ULONG  Divisor,
  IN OUT PULONG  Remainder);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlEnlargedUnsignedMultiply(
  IN ULONG  Multiplicand,
  IN ULONG  Multiplier);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlExtendedIntegerMultiply(
  IN LARGE_INTEGER  Multiplicand,
  IN LONG  Multiplier);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlExtendedLargeIntegerDivide(
  IN LARGE_INTEGER  Dividend,
  IN ULONG  Divisor,
  IN OUT PULONG  Remainder);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlExtendedMagicDivide(
  IN LARGE_INTEGER  Dividend,
  IN LARGE_INTEGER  MagicDivisor,
  IN CCHAR  ShiftCount);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerAdd(
  IN LARGE_INTEGER  Addend1,
  IN LARGE_INTEGER  Addend2);

NTOSAPI
VOID
DDKAPI
RtlLargeIntegerAnd(
  IN OUT LARGE_INTEGER  Result,
  IN LARGE_INTEGER  Source,
  IN LARGE_INTEGER  Mask);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerArithmeticShift(
  IN LARGE_INTEGER  LargeInteger,
  IN CCHAR  ShiftCount);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerDivide(
  IN LARGE_INTEGER  Dividend,
  IN LARGE_INTEGER  Divisor,
  IN OUT PLARGE_INTEGER  Remainder);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerEqualTo(
  IN LARGE_INTEGER  Operand1,
  IN LARGE_INTEGER  Operand2);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerEqualToZero(
  IN LARGE_INTEGER  Operand);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerGreaterOrEqualToZero(
  IN LARGE_INTEGER  Operand);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerGreaterThan(
  IN LARGE_INTEGER  Operand1,
  IN LARGE_INTEGER  Operand2);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerGreaterThanOrEqualTo(
  IN LARGE_INTEGER  Operand1,
  IN LARGE_INTEGER  Operand2);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerGreaterThanZero(
  IN LARGE_INTEGER  Operand);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerLessOrEqualToZero(
  IN LARGE_INTEGER  Operand);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerLessThan(
  IN LARGE_INTEGER  Operand1,
  IN LARGE_INTEGER  Operand2);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerLessThanOrEqualTo(
  IN LARGE_INTEGER  Operand1,
  IN LARGE_INTEGER  Operand2);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerLessThanZero(
  IN LARGE_INTEGER  Operand);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerNegate(
  IN LARGE_INTEGER  Subtrahend);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerNotEqualTo(
  IN LARGE_INTEGER  Operand1,
  IN LARGE_INTEGER  Operand2);

NTOSAPI
BOOLEAN
DDKAPI
RtlLargeIntegerNotEqualToZero(
  IN LARGE_INTEGER  Operand);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerShiftLeft(
  IN LARGE_INTEGER  LargeInteger,
  IN CCHAR  ShiftCount);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerShiftRight(
  IN LARGE_INTEGER  LargeInteger,
  IN CCHAR  ShiftCount);

NTOSAPI
LARGE_INTEGER
DDKAPI
RtlLargeIntegerSubtract(
  IN LARGE_INTEGER  Minuend,
  IN LARGE_INTEGER  Subtrahend);


/*
 * ULONG
 * COMPUTE_PAGES_SPANNED(
 *   IN PVOID  Va,
 *   IN ULONG  Size)
 */
#define COMPUTE_PAGES_SPANNED(Va, \
                              Size) \
  (ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va, Size))


/*
** Architecture specific functions
*/

#ifdef _X86_

NTOSAPI
INTERLOCKED_RESULT
DDKAPI
Exi386InterlockedIncrementLong(
  IN PLONG  Addend);

NTOSAPI
INTERLOCKED_RESULT
DDKFASTAPI
Exfi386InterlockedIncrementLong(
  IN PLONG  Addend);

NTOSAPI
INTERLOCKED_RESULT
DDKAPI
Exi386InterlockedDecrementLong(
  IN PLONG  Addend);

NTOSAPI
INTERLOCKED_RESULT
DDKFASTAPI
Exfi386InterlockedDecrementLong(
  IN PLONG  Addend);

NTOSAPI
ULONG
DDKAPI
Exi386InterlockedExchangeUlong(
  IN PULONG  Target,
  IN ULONG  Value);

NTOSAPI
ULONG
DDKFASTAPI
Exfi386InterlockedExchangeUlong(
  IN PULONG  Target,
  IN ULONG  Value);

#define ExInterlockedIncrementLong(Addend,Lock) Exfi386InterlockedIncrementLong(Addend)
#define ExInterlockedDecrementLong(Addend,Lock) Exfi386InterlockedDecrementLong(Addend)
#define ExInterlockedExchangeUlong(Target, Value, Lock) Exfi386InterlockedExchangeUlong(Target, Value)

#endif /* _X86_ */

#ifdef __cplusplus
}
#endif

#endif /* __WINNT4_H */
