//----------------------------------------------------------------------------
// Copyright 2005-2025 Joe Lowe
//
// Permission is granted to any person obtaining a copy of this Software,
// to deal in the Software without restriction, including the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and sell copies of
// the Software.
//
// The above copyright and permission notice must be left intact in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS WITHOUT WARRANTY.
//----------------------------------------------------------------------------
// file name:  fsrcontrol.h
// created:    2005.12.02
//----------------------------------------------------------------------------
#ifndef FSRCONTROL_H
#define FSRCONTROL_H
#include "ptioctl.h"
#include "ptipcpin.h"
#include "fsrprefix.h"
#include "fsrenum.h"

PT_STATIC_CONST( int, fsrVersion               , 12);
PT_STATIC_CONST( int, fsrMinDriverCompatVersion, 10);
PT_STATIC_CONST( int, fsrMinClientCompatVersion, 10);
// version change history:
//    version 1 - 2007.12.31
//      first release
//    version 2 - 2008.01.25
//      auth handles now optional when creating mounts
//      fsWaitReady added
//    version 3 - 2008.02.12
//      drive letter added to mount FsrMountInput struct and
//        FsGetMountInfoOutput
//    version 4 - 2008.11.04
//      improved handling of process visible mounts (SxS load error fix)
//    version 5 - 2009.02.26
//      fastpipe support
//    version 6 - 2015.03.25
//      dropped virtual mount point support
//      new device and file versioned name convention
//      strings all utf8
//    version 7 - 2015.04.xx
//      separated mount name into end name and source name
//    version 8 - 2015.04.xx
//      report
//    version 9 - 2019.03.25
//    version 10 - 2022.02.01
//      change from PFM to FSR
//    version 11 - 2022.x.x
//      PTSST.1 , secure transport
//      mount point can be specified to control end name
//    version 12 - 2024.x.x
//      mount ram cache size
//      mount persistent cache support
//    version 13 - 2025.09.10
//      composite transport support

#define FSR_KERNELCONTROLINTERFACEID  "com.pismotec.fsr.control"
#define FSR_KERNELDIRECTINTERFACEID "com.pismotec.fsr.direct"
#define FSR_TCP_DEVICENAME "com.pismotec.tcp"
#define FSR_CONTROLNAMEFILTER FSR_KERNELNAMEPREFIX "*.control"
#define FSR_CONTROLNAME FSR_KERNELBASENAME ".control"
#define FSR_MOUNT_LIST_IPCPIN_NAME "com.pismotec.fsr.mount_list_change"
#ifdef _WIN32
#define FSR_KERNELNAMESUFFIX ".sys"
#define FSR_KERNELFOLDER "C:\\Windows\\System32\\Drivers"
#ifndef _WIN64
#define FSR_ALTKERNELFOLDER "C:\\Windows\\Sysnative\\Drivers"
#endif
#define FSR_CONTROLDEVICENAME "\\Device\\" FSR_CONTROLNAME
#define FSR_FSRECDEVICENAME "\\Device\\" FSR_KERNELBASENAME ".fsrec"
#define FSR_ROOTDEVICENAME "\\Device\\" FSR_KERNELBASENAME
#define FSR_VOLDEVICENAMEFORMAT "\\Device\\" FSR_KERNELBASENAME ".vol%u"
#define FSR_VOLUMEFOLDER "C:\\Volumes"
#define FSR_UNCPREFIX "\\\\-"
#define FSR_UNCPREFIXW L"\\\\-"
#define FSR_STARTLOCKNAME "C:\\Windows\\Temp\\fsr-start.lock"
#define FSR_SHELL_FILENAME "fsrshell" PT_EXESUFFIXA
#define FSR_SHELL_SIGNALSOCKETFORMAT2 "fsrshell-signal-%s-%s.socket"
#define FSR_SYSTEM_BIN_FOLDER "C:\\Windows"
#define FSR_SYSTEM_LIB_FOLDER "C:\\Windows\\system32"
#define FSR_UNC_PROVIDER_NAME "com.pismotec.fsr.unc"
#else
#define FSR_CONTROLDEVICENAME "/dev/" FSR_KERNELBASENAME ".control"
#define FSR_STARTLOCKNAME "/var/run/com.pismotec.fsr.start.lock"
#define FSR_SYSTEM_BIN_FOLDER "/usr/local/bin"
#define FSR_SYSTEM_LIB_FOLDER "/usr/local/lib"
#ifdef __APPLE__
#define FSR_KERNELNAMESUFFIX ".kext"
#define FSR_KERNELFOLDER "/Library/Extensions"
#define FSR_VOLUMEFOLDER "/Volumes"
#else
#define FSR_KERNELNAMESUFFIX ".kmod"
#define FSR_KERNELFOLDER "/lib/modules"
#define FSR_VOLUMEFOLDER "/media"
#endif
#endif
#define FSR_KERNELBASENAMEFILTER FSR_KERNELNAMEPREFIX "*"
#define FSR_CMD_FILENAME FSR_FILENAMEPREFIX "cmd" PT_EXESUFFIXA
#define FSR_SUPPORT_FILENAME FSR_FILENAMEPREFIX "support" PT_EXESUFFIXA

   // Control codes sent as function portion of device unknown
   // vendor specific buffered IOCTL to API device.
   // ioctl = (PT_GENIOCTLBASE | (func << PT_IOCTLFUNCSHIFT))

PT_STATIC_CONST( int, fsrMount                 , 3  );
PT_STATIC_CONST( int, fsrSelectMountId         , 5  );
PT_STATIC_CONST( int, fsrGetMountList          , 6  );
PT_STATIC_CONST( int, fsrCheckSupport          , 14 );
PT_STATIC_CONST( int, fsrCancel                , 18 );
PT_STATIC_CONST( int, fsrSupportPump           , 21 );
PT_STATIC_CONST( int, fsrCreateDriveLetterLink , 22 );
PT_STATIC_CONST( int, fsrDeleteDriveLetterLink , 23 );
PT_STATIC_CONST( int, fsrHoldFd                , 24 );
PT_STATIC_CONST( int, fsrCacheLoad             , 25 );
PT_STATIC_CONST( int, fsrCacheUnload           , 26 );
PT_STATIC_CONST( int, fsrCachePoll             , 27 );
PT_STATIC_CONST( int, fsrCreateCompositeSocket , 28 );

   // Control codes sent after mount has been created or selected.
PT_STATIC_CONST( int, fsrUnmount               , 101);
PT_STATIC_CONST( int, fsrFlush                 , 103);
PT_STATIC_CONST( int, fsrGetMountInfo          , 106);
PT_STATIC_CONST( int, fsrGetReport             , 108);

   // Range of control codes that tunnel through to selected mount formatter.
PT_STATIC_CONST( int, fsrControlStart          , 300);
PT_STATIC_CONST( int, fsrControlEnd            , 399);

   // Range of control codes passed to xway networking.
PT_STATIC_CONST( int, fsrXwayStart             , 400);
PT_STATIC_CONST( int, fsrXwayEnd               , 499);

   // Control codes sent to open file or folder fd's on PFM
   // volumes.
   // ioctl = (PT_GENIOCTLBASE | (((startCode + code) << IOCTLFUNCSHIFT))

PT_STATIC_CONST( int, fsrDirectGetRootMountInfo, 1  );
PT_STATIC_CONST( int, fsrDirectGetMountInfo    , 2  );

   // Range of control codes that tunnel through to formatter.
PT_STATIC_CONST( int, fsrDirectControlStart    , 100);
PT_STATIC_CONST( int, fsrDirectControlEnd      , 199);


   // Control codes sent as function portion of device unknown vendor
   // specific unbuffered IOCTL to API device.
   // ioctl = (PT_UNBUFGENIOCTLBASE | (func << IOCTLFUNCSHIFT))

// static const int fsXxx            = 51;

PT_TYPE_DEFINE( FsrMountInput)
{
   int mountFlags;
   char driveLetterReserved1;
   PT_UINT8 reserved2[3];
   union { FD_T transport; PT_INT64 pad1; };
   union { FD_T transportReserved3; PT_INT64 pad2; };
   union { FD_T watchdog; PT_INT64 pad3; };
   PT_UINT64 ramCacheSize;
   PT_UINT8 reserved4[20];
   int timeout;
   pt_ipcpin_name_t cancelPinName;
   char strings[32];
   // char mountSourceName[ strlen( mountSourceName) + 1];
   // char ownerId[ strlen( ownerId) + 1];
   // char appId[ strlen( appId) + 1];
   // char transportSecurity[ strlen( transportSecurity) + 1];
   // char mountPoint[ strlen( mountPoint) + 1];
   // char cacheStorageId[ strlen( cacheStorageId) + 1];
   // char cacheVolumeId[ strlen( cacheVolumeId) + 1];
   // char cacheKey[ strlen( cacheKey) + 1];
   // char driveLetter[ strlen( driveLetter) + 1];
};
PT_C_ASSERT1( sizeof( FsrMountInput) == 0x80);

PT_TYPE_DEFINE( FsrMountOutput)
{
   int mountId;
   unsigned reserved[1];
};

PT_TYPE_DEFINE( FsrSelectMountIdInput)
{
   int mountId;
   unsigned reserved[1];
};

PT_TYPE_DEFINE( FsrGetMountInfoOutput)
{
   unsigned outputSize;
   PT_UINT8 reserved1[4];
   int mountId;
   PT_UINT8 reserved2[4];
   int mountFlags;
   int statusFlags;
   int volumeFlags;
   char driveLetter;
   PT_UINT8 reserved3[3];
   PT_UINT64 softCacheSize;
   PT_UINT8 reserved4[24];
   char strings[64];
   // char controlDevName[ strlen( controlDevName) + 1];
   // char mountSourceName[ strlen( mountSourceName) + 1];
   // char uncName[ strlen( uncName) + 1];
   // char ownerId[ strlen( ownerId) + 1];
   // char formatterName[ strlen( formatterName) + 1];
   // char mountPoint[ strlen( mountPoint) + 1];
   // char mountEndName[ strlen( mountEndName) + 1];
   // char appId[ strlen( appId)+1];
};
PT_C_ASSERT1( sizeof( FsrGetMountInfoOutput) == 0x80);

PT_TYPE_DEFINE( FsrMountListEntry)
{
   int mountId;
   PT_UINT8 reserved1[12];
};

PT_TYPE_DEFINE( FsrGetMountListOutput)
{
   unsigned outputSize;
   unsigned driveLetterMask;
   PT_UINT8 reserved1[18];
   unsigned mountCount;
   PT_UINT8 reserved2[12];
   FsrMountListEntry mountList[ 1/*mountCount*/];
};

PT_TYPE_DEFINE( FsrUnmountInput)
{
   int unmountFlags;
   PT_UINT8 reserved1[12];
};

PT_TYPE_DEFINE( FsrGetReportInput)
{
   int reportFlags;
   PT_UINT8 reserved[4];
};

PT_TYPE_DEFINE( FsrCreateDriveLetterLinkInput)
{
   char driveLetter;
   char target[1];
};

PT_TYPE_DEFINE( FsrDeleteDriveLetterLinkInput)
{
   char driveLetter;
};

PT_TYPE_DEFINE( FsrHoldFdInput)
{
   pt_uuid_t id;
   int send_fd;
   int recv_fd;
};

PT_TYPE_DEFINE( FsrHoldFdOutput)
{
   int fd;
};

PT_TYPE_DEFINE( FsrCacheLoadInput)
{
   union { FD_T storageFd; PT_INT64 pad1; };
   PT_UINT64 storageOff;
   PT_UINT64 storageSize;
   PT_UINT8 reserved1[40];
};

PT_TYPE_DEFINE( FsrCacheLoadOutput)
{
   char handle[64];
   PT_UINT8 reserved1[64];
};

PT_TYPE_DEFINE( FsrCreateCompositeSocketInput)
{
   uint8_t reserved1[32];
   union { PT_SIZE_T chunk_size; PT_UINT64 pad1; };
   union { PT_SIZE_T member_count; PT_UINT64 pad2; };
   union { FD_T fd; PT_UINT64 pad3; } member_table[10];
};

PT_TYPE_DEFINE( fsr_support_req_t)
{
   int cookie;
   int code_err;
};

   // Inverted support call codes and parameter/result structures.
PT_STATIC_CONST( int, fsrSupportMkdir        ,  2);
PT_STATIC_CONST( int, fsrSupportRmdir        ,  3);
PT_STATIC_CONST( int, fsrSupportMount        ,  4);
PT_STATIC_CONST( int, fsrSupportUnmount      ,  5);
PT_STATIC_CONST( int, fsrSupportHoldFd       , 10);
PT_STATIC_CONST( int, fsrSupportXwayStart    , 50);
PT_STATIC_CONST( int, fsrSupportXwayEnd      , 99);

PT_TYPE_DEFINE( FsrSupportMountInput)
{
   int mount_id;
   PT_UINT8 reserved1[60];
   char fs_name_and_mount_point[8];
};

PT_TYPE_DEFINE( FsrSupportUnmountInput)
{
   PT_UINT8 reserved1[64];
   char mount_point[8];
};

PT_TYPE_DEFINE( FsrSupportHoldFdInput)
{
   pt_uuid_t id;
};

#define fsrCacheInterfaceId "com.pismotec.fsrcache"
PT_STATIC_CONST( int, fsrCacheControlGetFileStatus, 0x02);

#endif
