/*
 * hid/shared_mem.h
 *
 * Owner of the VhidkmShared named section object.
 *
 * The section backs the single IPC channel between user-mode
 * injection clients and the vhidkm.sys DISPATCH_LEVEL timer. The
 * driver:
 *
 *   - creates a kernel section in \BaseNamedObjects\Global\ with an
 *     explicit DACL granting SYSTEM + BUILTIN\Administrators full
 *     access and nothing to anyone else;
 *   - maps it once into system space so the injection timer can
 *     touch it without any IRQL transition;
 *   - keeps the creating handle open for the lifetime of the device
 *     so the name persists in the namespace and user-mode OpenFile-
 *     MappingW calls keep resolving;
 *   - initializes the header fields (Magic, Version, HeaderBytes,
 *     HeartbeatMs) before returning;
 *   - tears everything down symmetrically in destroy.
 *
 * The module does not own concurrency over the section — the seqlock
 * protocol defined in common/vhid_shared.h is the only contract
 * between user-mode writers and the kernel consumer.
 */

#pragma once
#ifndef VHID_HID_SHARED_MEM_H_
#define VHID_HID_SHARED_MEM_H_

#include "driver.h"
#include "vhid_shared.h"

typedef struct _VHIDKM_SHARED_SECTION {
    HANDLE               SectionHandle;  /* kernel handle; kept open so the
                                            name stays in \BaseNamedObjects */
    PVOID                SectionObject;  /* referenced pointer passed to
                                            MmMapViewInSystemSpace          */
    PVHID_SHARED_STATE   View;           /* system-space mapping, always
                                            resident                        */
    SIZE_T               ViewSize;       /* actual map size, >= sizeof()    */
} VHIDKM_SHARED_SECTION, *PVHIDKM_SHARED_SECTION;

/*
 * Create the section, publish its name, map it into system space, and
 * stamp the header fields. Runs at PASSIVE_LEVEL during device start.
 * On success the caller owns the VHIDKM_SHARED_SECTION and is
 * responsible for eventually calling VhidkmSharedSectionDestroy.
 */
_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS
VhidkmSharedSectionCreate(
    _Out_ PVHIDKM_SHARED_SECTION Shared
    );

/*
 * Unmap, dereference, and close. Idempotent — safe to call with a
 * zeroed structure if the create attempt failed partway through.
 */
_IRQL_requires_(PASSIVE_LEVEL)
VOID
VhidkmSharedSectionDestroy(
    _Inout_ PVHIDKM_SHARED_SECTION Shared
    );

/*
 * LED publish helper. Writes LedBits + memory-barrier + Interlocked-
 * Increment(LedSeq). DISPATCH_LEVEL-safe; called from the HID
 * SET_OUTPUT_REPORT path.
 */
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
VhidkmSharedSectionPublishLeds(
    _In_ PVHIDKM_SHARED_SECTION Shared,
    _In_ UCHAR LedBits
    );

#endif /* VHID_HID_SHARED_MEM_H_ */
