#ifndef SCSI_STRUCTS_H
#define SCSI_STRUCTS_H

#include <windows.h>
#include <stdint.h>

// Force the compiler to NOT add padding bytes
#pragma pack(push, 8)

typedef struct _SCSI_PASS_THROUGH {
    uint16_t Length;
    uint8_t  ScsiStatus;
    uint8_t  PathId;
    uint8_t  TargetId;
    uint8_t  Lun;
    uint8_t  CdbLength;
    uint8_t  SenseInfoLength;
    uint8_t  DataIn;
    uint32_t DataTransferLength;
    uint32_t TimeOutValue;
    uint32_t DataBufferOffset;
    uint32_t SenseInfoOffset;
    uint8_t  Cdb[16];
} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;

typedef struct _SCSI_PASS_THROUGH_DIRECT {
    uint16_t Length;
    uint8_t  ScsiStatus;
    uint8_t  PathId;
    uint8_t  TargetId;
    uint8_t  Lun;
    uint8_t  CdbLength;
    uint8_t  SenseInfoLength;
    uint8_t  DataIn;
    uint32_t DataTransferLength;
    uint32_t TimeOutValue;
    void* DataBuffer;
    uint32_t SenseInfoOffset;
    uint8_t  Cdb[16];
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;

typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER {
    SCSI_PASS_THROUGH_DIRECT Spt;
    uint32_t Filler;
    uint8_t  SenseBuf[32]; // Note: Ensure your code uses SenseBuf, not SenseBuffer
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;

#pragma pack(pop)

// Manually define SCSI constants if headers are missing

#ifndef IOCTL_SCSI_PASS_THROUGH_DIRECT
#define IOCTL_SCSI_PASS_THROUGH_DIRECT 0x4D014
#endif

#ifndef IOCTL_SCSI_PASS_THROUGH
#define IOCTL_SCSI_PASS_THROUGH 0x0004D004
#endif

#ifndef SCSI_IOCTL_DATA_OUT
#define SCSI_IOCTL_DATA_OUT 0
#endif

#ifndef SCSI_IOCTL_DATA_IN
#define SCSI_IOCTL_DATA_IN 1
#endif

#ifndef SCSI_IOCTL_DATA_UNSPECIFIED
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
#endif

#ifndef FSCTL_LOCK_VOLUME
#define FSCTL_LOCK_VOLUME 0x00090018
#endif
#ifndef FSCTL_DISMOUNT_VOLUME
#define FSCTL_DISMOUNT_VOLUME 0x00090020
#endif

#ifndef FSCTL_UNLOCK_VOLUME
#define FSCTL_UNLOCK_VOLUME 0x0009001c
#endif

#endif