mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	Create common.h
This commit is contained in:
		
							
								
								
									
										212
									
								
								tst/airfs/common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								tst/airfs/common.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,212 @@ | ||||
| /** | ||||
|  * @file common.h | ||||
|  * | ||||
|  * @copyright 2015-2019 Bill Zissimopoulos | ||||
|  */ | ||||
| /* | ||||
|  * This file is part of WinFsp. | ||||
|  * | ||||
|  * You can redistribute it and/or modify it under the terms of the GNU | ||||
|  * General Public License version 3 as published by the Free Software | ||||
|  * Foundation. | ||||
|  * | ||||
|  * Licensees holding a valid commercial license may use this software | ||||
|  * in accordance with the commercial license agreement provided in | ||||
|  * conjunction with the software.  The terms and conditions of any such | ||||
|  * commercial license agreement shall govern, supersede, and render | ||||
|  * ineffective any application of the GPLv3 license to this software, | ||||
|  * notwithstanding of any reference thereto in the software or | ||||
|  * associated repository. | ||||
|  */ | ||||
| /* | ||||
|  * Airfs is based on Memfs with changes contributed by John Oberschelp. | ||||
|  * The contributed changes are under joint copyright by Bill Zissimopoulos | ||||
|  * and John Oberschelp per the Contributor Agreement found at the | ||||
|  * root of this project. | ||||
|  */ | ||||
|  | ||||
| #include <winfsp/winfsp.h> | ||||
| #include <io.h> | ||||
| #include <sddl.h> | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #define PROGNAME "airfs" | ||||
| #define ROUND_UP(   bytes, units )  (((bytes) + (units) - 1) / (units) * (units)) | ||||
| #define ROUND_DOWN( bytes, units )  (((bytes)              ) / (units) * (units)) | ||||
| #define MINIMUM_ALLOCSIZE 196 | ||||
| #define MAXIMUM_ALLOCSIZE ROUND_DOWN(10*1024*1024, MINIMUM_ALLOCSIZE) | ||||
| #define SECTOR_SIZE                   512 | ||||
| #define SECTORS_PER_ALLOCATION_UNIT     1 | ||||
| #define ALLOCATION_UNIT ( SECTOR_SIZE * SECTORS_PER_ALLOCATION_UNIT ) | ||||
| #define INFO(format, ...) FspServiceLog(EVENTLOG_INFORMATION_TYPE , format, __VA_ARGS__) | ||||
| #define WARN(format, ...) FspServiceLog(EVENTLOG_WARNING_TYPE     , format, __VA_ARGS__) | ||||
| #define FAIL(format, ...) FspServiceLog(EVENTLOG_ERROR_TYPE       , format, __VA_ARGS__) | ||||
| #define AIRFS_MAX_PATH 512 | ||||
| #define FILEBLOCK_OVERHEAD 40  //  size of ( P + E + L + R + FileOffset ) = 8 * 5 = 40 | ||||
| #define ARG_TO_S(v) if (arge > ++argp) v = *argp; else goto usage | ||||
| #define ARG_TO_4(v) if (arge > ++argp) v = (int32_t) wcstoll_default(*argp, v); else goto usage | ||||
| #define ARG_TO_8(v) if (arge > ++argp) v =           wcstoll_default(*argp, v); else goto usage | ||||
|  | ||||
| enum StorageFileAccessType {ZERO=0,READ,WRITE}; | ||||
| enum Neighbor {LT=-2,LE=-1,EQ=0,GE=1,GT=2}; | ||||
|  | ||||
| struct  NODE; | ||||
| typedef NODE* NODE_; | ||||
|  | ||||
| typedef int CompareFunction (void* key,  NODE_); | ||||
|  | ||||
| inline NTSTATUS GetLastErrorAsStatus() | ||||
| { | ||||
|     return FspNtStatusFromWin32(GetLastError()); | ||||
| } | ||||
|  | ||||
| inline UINT64 SystemTime() | ||||
| { | ||||
|     FILETIME FileTime; | ||||
|     GetSystemTimeAsFileTime(&FileTime); | ||||
|     return ((PLARGE_INTEGER)&FileTime)->QuadPart; | ||||
| } | ||||
|  | ||||
| static int64_t wcstoll_default(wchar_t *w, int64_t deflt) | ||||
| { | ||||
|     wchar_t *endp; | ||||
|     int64_t i = wcstoll(w, &endp, 0); | ||||
|     return L'\0' != w[0] && L'\0' == *endp ? i : deflt; | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
| // | ||||
| //  Where<T> Class: This class manages an offset within our memory-mapped  | ||||
| //  volume to another location within our memory-mapped volume. Because it is | ||||
| //  a self-relative offset, this delta is constant regardless of where in | ||||
| //  memory the file system is mapped, so we can always reoptain its address.  | ||||
| //  A delta of 0 is the special case for "null". | ||||
| // | ||||
|  | ||||
| template <class T> class Where | ||||
| { | ||||
|     int64_t delta; | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     Where() = default; | ||||
|    ~Where() = default; | ||||
|     Where(T      t) : delta(  t      ?(  (char*)t          -(char*)this  ):0) {} | ||||
|     Where(Where& w) : delta(  w.delta?( ((char*)&w+w.delta)-(char*)this  ):0) {} | ||||
|  | ||||
|       operator bool  () { return delta != 0; } | ||||
|       operator T     () { return (T)    ( delta?(  (char*)this+delta   ):0); } | ||||
|     T operator ->    () { return (T)    ( delta?(  (char*)this+delta   ):0); } | ||||
|       operator void* () { return (void*)( delta?(  (char*)this+delta   ):0); } | ||||
|  | ||||
|     bool operator == (Where& rhs) { return (char*)this+delta == (char*)&rhs+rhs.delta; } | ||||
|     bool operator != (Where& rhs) { return (char*)this+delta != (char*)&rhs+rhs.delta; } | ||||
|     bool operator == (T rhs)      { return (char*)this+delta == (char*)rhs; } | ||||
|     bool operator != (T rhs)      { return (char*)this+delta != (char*)rhs; } | ||||
|  | ||||
|     Where& operator = (Where& rhs) { delta = rhs.delta?(  ((char*)&rhs+rhs.delta) - ((char*)this)  ):0; return *this; } | ||||
|     Where& operator = (void*  rhs) { delta = rhs      ?(   (char*)rhs             - ((char*)this)  ):0; return *this; } | ||||
|  | ||||
|     char* Address () { return (char*)this+delta; } | ||||
| }; | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
| // | ||||
| //  The header for an Airfs volume | ||||
| // | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     char         Signature[8];        //  Airfs\0\0\0 | ||||
|     char         MapFormatVersion[4]; //  Major.Minor.Patch.Build | ||||
|     char         filler[4]; | ||||
|     Where<NODE_> Root; | ||||
|     Where<NODE_> Available; | ||||
|     UINT64       VolumeSize; | ||||
|     UINT64       FreeSize; | ||||
|     WCHAR        VolumeLabel[32]; | ||||
|     UINT16       VolumeLabelLength; | ||||
|     UINT16       filler1,filler2,filler3; | ||||
|     UINT32       CaseInsensitive; | ||||
|     UINT32       filler4; | ||||
|     WCHAR        MapName[256]; | ||||
|     WCHAR        VolumeName[256];  //  Use "" for a memory-only page file. | ||||
|     int64_t      VolumeLength; | ||||
|     FSP_FSCTL_VOLUME_PARAMS VolumeParams; | ||||
|     FSP_FILE_SYSTEM *FileSystem; | ||||
|     HANDLE       MapFileHandle; | ||||
|     HANDLE       MapHandle; | ||||
| } AIRFS, *AIRFS_; | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
| // | ||||
| //  Information per file or directory | ||||
| // | ||||
| struct NODE | ||||
| { | ||||
|     Where<NODE_> P,L,R,E;  //  Sorted sibling tree: Parent, Left, Right, and Equal | ||||
|     union | ||||
|     { | ||||
|         Where<WCHAR*> Name; | ||||
|         int64_t FileOffset; | ||||
|     }; | ||||
|     Where<NODE_>  Parent; | ||||
|     Where<NODE_>  Children; | ||||
|     FSP_FSCTL_FILE_INFO FileInfo; | ||||
|     uint64_t      SecurityDescriptorSize; | ||||
|     Where<char*>  SecurityDescriptor; | ||||
|     Where<NODE_>  FileBlocks; | ||||
|     uint64_t      ReparseDataSize; | ||||
|     Where<char*>  ReparseData; | ||||
|     volatile LONG RefCount; | ||||
|     Where<NODE_>  Streams; | ||||
|     BOOLEAN       IsAStream; | ||||
| }; | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| class SpinLock | ||||
| { | ||||
|     LONG   C;  //  Counter | ||||
|     HANDLE S;  //  Semaphore | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     SpinLock() { C = 0; S = CreateSemaphore(NULL, 0, 1, NULL); } | ||||
|    ~SpinLock() { CloseHandle(S); } | ||||
|  | ||||
|     void Acquire() { if (_InterlockedIncrement(&C) > 1) WaitForSingleObject(S, INFINITE); } | ||||
|     void Release() { if (_InterlockedDecrement(&C) > 0) ReleaseSemaphore(S, 1, NULL); } | ||||
| }; | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void Airprint (const char * format, ...); | ||||
|  | ||||
| int           SizeCmp (void* key,  NODE_); | ||||
| int      ExactNameCmp (void* key,  NODE_); | ||||
| int   CaselessNameCmp (void* key,  NODE_); | ||||
|  | ||||
| NODE_ Find   (Where<NODE_> &root, void* key, CompareFunction); | ||||
| NODE_ Near   (Where<NODE_> &root, void* key, CompareFunction, Neighbor); | ||||
| void  Attach (Where<NODE_> &root, NODE_ attach, CompareFunction, void* key); | ||||
| void  Detach (Where<NODE_> &root, NODE_ detach); | ||||
| NODE_ First  (NODE_ start); | ||||
| NODE_ Last   (NODE_ start); | ||||
| NODE_ Next   (NODE_); | ||||
| NODE_ Prev   (NODE_); | ||||
|  | ||||
| NTSTATUS StorageStartup         (AIRFS_ &, WCHAR* MapName, WCHAR* VolumeName, int64_t Length); | ||||
| NTSTATUS StorageShutdown        (AIRFS_); | ||||
| void*    StorageAllocate        (AIRFS_ Airfs, int64_t RequestedSize); | ||||
| void*    StorageReallocate      (AIRFS_ Airfs, void* Reallocate, int64_t RequestedSize); | ||||
| void     StorageFree            (AIRFS_ Airfs, void* Release); | ||||
| NTSTATUS StorageSetFileCapacity (AIRFS_, NODE_, int64_t MinimumRequiredCapacity); | ||||
| void     StorageAccessFile      (StorageFileAccessType, NODE_, int64_t Offset, int64_t NumBytes, char* Address); | ||||
|  | ||||
| static_assert(AIRFS_MAX_PATH > MAX_PATH, "AIRFS_MAX_PATH must be greater than MAX_PATH."); | ||||
| static_assert(sizeof NODE + sizeof int32_t == MINIMUM_ALLOCSIZE, "MINIMUM_ALLOCSIZE should be 196."); | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
| ////////////////////////////////////////////////////////////////////// | ||||
		Reference in New Issue
	
	Block a user