[+] File System devices API
[+] AuFS::EFSDeviceType [+] AuFS::EFSBusType [+] AuFS::LogicalUsedResponse [+] AuFS::LogicalOffsetResponse [+] AuFS::FSLogicalPartition [+] AuFS::FSDevice [+] AuFS::GetRootFromPath [+] AuFS::GetDeviceFromPath [+] AuFS::GetDeviceFromRoot [+] AuFS::GetLogicalMountFromPath [+] AuFS::TrySimplifyDevicePath [+] AuFS::GetPerformanceBufferSizeFromPath [+] AuFS::GetPhysicalSectorSizeFromPath [+] AuFS::GetLogicalSectorSizeFromPath [+] AuFS::GetLogicalUsedFromPath [+] AuFS::GetLogicalUsedFromLogicalDevice [+] AuFS::GetDeviceSizeInBytes [+] AuFS::GetDeviceModel [+] AuFS::GetFSDeviceByFilePath [+] AuFS::GetFSDeviceByDevice [+] AuFS::GetFSDevices [+] AuFS::GetFSDevicesCachedUnsafe [+] AuFS::ResetDeviceCache [+] FSPlatformDevices.cpp [+] FSPlatformDevices.NT.cpp (holding back Linux)
This commit is contained in:
parent
b65d0032dd
commit
b35b290afd
99
Include/Aurora/IO/FS/Devices.hpp
Normal file
99
Include/Aurora/IO/FS/Devices.hpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: Devices.hpp
|
||||||
|
Date: 2023-08-11
|
||||||
|
Date: 2023-12-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
AUE_DEFINE(EFSDeviceType, (
|
||||||
|
eDeviceDisk,
|
||||||
|
eDeviceSCSI,
|
||||||
|
eDeviceCD,
|
||||||
|
eDeviceUSBMass,
|
||||||
|
eDeviceFloppy,
|
||||||
|
eDeviceNetworkMount,
|
||||||
|
eDeviceRamDisk,
|
||||||
|
eDeviceROMWindow,
|
||||||
|
eDeviceUnknown
|
||||||
|
))
|
||||||
|
|
||||||
|
AUE_DEFINE(EFSBusType, (
|
||||||
|
eBusGeneric,
|
||||||
|
eBusSCSI,
|
||||||
|
eBusSATA,
|
||||||
|
eBusUSB,
|
||||||
|
eBusNetwork
|
||||||
|
))
|
||||||
|
|
||||||
|
struct LogicalUsedResponse
|
||||||
|
{
|
||||||
|
AuUInt64 uLogicalSize {};
|
||||||
|
AuUInt64 uLogicalUsed {};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LogicalOffsetResponse
|
||||||
|
{
|
||||||
|
AuUInt64 uLogicalSize {};
|
||||||
|
AuUInt64 uLogicalOffset {};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSLogicalPartition
|
||||||
|
{
|
||||||
|
AuString devicePath;
|
||||||
|
AuString logicalMount;
|
||||||
|
AuList<AuString> filesystemMountPoints;
|
||||||
|
AuOptional<AuString> name;
|
||||||
|
LogicalUsedResponse space;
|
||||||
|
LogicalOffsetResponse offset;
|
||||||
|
bool bIsReadOnly {};
|
||||||
|
uuids::uuid uuid;
|
||||||
|
// ... ?
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSDevice
|
||||||
|
{
|
||||||
|
EFSDeviceType type;
|
||||||
|
EFSBusType bus;
|
||||||
|
AuString devicePath;
|
||||||
|
AuString productModel;
|
||||||
|
AuOptional<AuString> altLabel;
|
||||||
|
AuOptional<AuString> altProductDescription;
|
||||||
|
AuList<FSLogicalPartition> partitions;
|
||||||
|
AuUInt64 uFSDeviceSizeInBytes {};
|
||||||
|
AuUInt64 uFSDevicePageSizeInBytes {};
|
||||||
|
uuids::uuid uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
AUKN_SYM AuString GetRootFromPath(const AuString &fileOrDirPath);
|
||||||
|
|
||||||
|
AUKN_SYM AuResult<AuString> GetDeviceFromPath(const AuString &fileOrDirPath);
|
||||||
|
AUKN_SYM AuResult<AuString> GetDeviceFromRoot(const AuString &root);
|
||||||
|
AUKN_SYM AuResult<AuString> GetLogicalMountFromPath(const AuString &fileOrDirPath);
|
||||||
|
|
||||||
|
AUKN_SYM AuString TrySimplifyDevicePath(const AuString &deviceOrLogicalMountPath);
|
||||||
|
|
||||||
|
// max: unbuffered pipe io
|
||||||
|
AUKN_SYM AuUInt32 GetPerformanceBufferSizeFromPath(const AuString &fileOrDirPath);
|
||||||
|
// min: unbuffered pipe io
|
||||||
|
AUKN_SYM AuUInt32 GetPhysicalSectorSizeFromPath(const AuString &fileOrDirPath);
|
||||||
|
// min viable sector size with abstractions on top of the disk
|
||||||
|
AUKN_SYM AuUInt32 GetLogicalSectorSizeFromPath(const AuString &fileOrDirPath);
|
||||||
|
|
||||||
|
AUKN_SYM LogicalUsedResponse GetLogicalUsedFromPath(const AuString &fileOrDirPath);
|
||||||
|
AUKN_SYM LogicalUsedResponse GetLogicalUsedFromLogicalDevice(const AuString &logicalMountPath);
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 GetDeviceSizeInBytes(const AuString& physicalDevicePath);
|
||||||
|
|
||||||
|
AUKN_SYM AuResult<AuString> GetDeviceModel(const AuString& physicalDevicePath);
|
||||||
|
|
||||||
|
AUKN_SYM AuResult<FSDevice> GetFSDeviceByFilePath(const AuString &fileOrDirPath);
|
||||||
|
AUKN_SYM AuResult<FSDevice> GetFSDeviceByDevice(const AuString &physicalDevicePath);
|
||||||
|
AUKN_SYM AuList<FSDevice> GetFSDevices();
|
||||||
|
AUKN_SYM const AuList<FSDevice> &GetFSDevicesCachedUnsafe();
|
||||||
|
AUKN_SYM void ResetDeviceCache();
|
||||||
|
}
|
@ -106,6 +106,8 @@ namespace Aurora
|
|||||||
ADD_LOAD_LIB(IPHelper);
|
ADD_LOAD_LIB(IPHelper);
|
||||||
ADD_LOAD_LIB(COM);
|
ADD_LOAD_LIB(COM);
|
||||||
ADD_LOAD_LIB(User32);
|
ADD_LOAD_LIB(User32);
|
||||||
|
ADD_LOAD_LIB(SetupAPI);
|
||||||
|
ADD_LOAD_LIB(Router);
|
||||||
|
|
||||||
#define ADD_GET_PROC(name, proc) \
|
#define ADD_GET_PROC(name, proc) \
|
||||||
if (!IsBlocked(#proc)) \
|
if (!IsBlocked(#proc)) \
|
||||||
@ -177,6 +179,8 @@ namespace Aurora
|
|||||||
ADD_GET_PROC(Nt, NtQueryInformationProcess)
|
ADD_GET_PROC(Nt, NtQueryInformationProcess)
|
||||||
ADD_GET_PROC(Nt, NtNotifyChangeDirectoryFile)
|
ADD_GET_PROC(Nt, NtNotifyChangeDirectoryFile)
|
||||||
ADD_GET_PROC(Nt, NtTerminateProcess)
|
ADD_GET_PROC(Nt, NtTerminateProcess)
|
||||||
|
ADD_GET_PROC(Nt, NtQuerySymbolicLinkObject)
|
||||||
|
ADD_GET_PROC(Nt, NtOpenSymbolicLinkObject)
|
||||||
|
|
||||||
ADD_GET_PROC_BI(Kernel32, KernelBase, VirtualAlloc2)
|
ADD_GET_PROC_BI(Kernel32, KernelBase, VirtualAlloc2)
|
||||||
ADD_GET_PROC_BI(Kernel32, KernelBase, MapViewOfFile3)
|
ADD_GET_PROC_BI(Kernel32, KernelBase, MapViewOfFile3)
|
||||||
@ -280,6 +284,18 @@ namespace Aurora
|
|||||||
ADD_GET_PROC(User32, SetPropW);
|
ADD_GET_PROC(User32, SetPropW);
|
||||||
ADD_GET_PROC(User32, OpenClipboard);
|
ADD_GET_PROC(User32, OpenClipboard);
|
||||||
|
|
||||||
|
ADD_GET_PROC(SetupAPI, SetupDiEnumDeviceInterfaces);
|
||||||
|
ADD_GET_PROC(SetupAPI, SetupDiDestroyDeviceInfoList);
|
||||||
|
ADD_GET_PROC(SetupAPI, SetupDiGetClassDevsW);
|
||||||
|
ADD_GET_PROC(SetupAPI, SetupDiGetDeviceRegistryPropertyA);
|
||||||
|
ADD_GET_PROC(SetupAPI, SetupDiGetDeviceInterfaceDetailW);
|
||||||
|
|
||||||
|
ADD_GET_PROC(Router, WNetCloseEnum);
|
||||||
|
ADD_GET_PROC(Router, WNetEnumResourceW);
|
||||||
|
ADD_GET_PROC(Router, WNetOpenEnumW);
|
||||||
|
ADD_GET_PROC(Router, WNetGetUniversalNameW);
|
||||||
|
|
||||||
|
|
||||||
if (pNtCreateKeyedEvent &&
|
if (pNtCreateKeyedEvent &&
|
||||||
Threading::Primitives::gKeyedEventHandle == INVALID_HANDLE_VALUE)
|
Threading::Primitives::gKeyedEventHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,10 @@ struct _IP_ADAPTER_INFO;
|
|||||||
struct _CREATEFILE2_EXTENDED_PARAMETERS;
|
struct _CREATEFILE2_EXTENDED_PARAMETERS;
|
||||||
struct _EXPLICIT_ACCESS_A;
|
struct _EXPLICIT_ACCESS_A;
|
||||||
struct _ACL;
|
struct _ACL;
|
||||||
|
struct _SP_DEVINFO_DATA;
|
||||||
|
struct _SP_DEVICE_INTERFACE_DATA;
|
||||||
|
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W;
|
||||||
|
struct _NETRESOURCEW;
|
||||||
enum _SE_OBJECT_TYPE;
|
enum _SE_OBJECT_TYPE;
|
||||||
enum _MINIDUMP_TYPE;
|
enum _MINIDUMP_TYPE;
|
||||||
|
|
||||||
@ -56,6 +60,8 @@ namespace Aurora
|
|||||||
static const wchar_t *kIPHelperDllName { L"IPHLPAPI.dll" };
|
static const wchar_t *kIPHelperDllName { L"IPHLPAPI.dll" };
|
||||||
static const wchar_t *kCOMDllName { L"ole32.dll" };
|
static const wchar_t *kCOMDllName { L"ole32.dll" };
|
||||||
static const wchar_t *kUser32DllName { L"User32.dll" };
|
static const wchar_t *kUser32DllName { L"User32.dll" };
|
||||||
|
static const wchar_t *kSetupAPIDllName { L"SETUPAPI.dll" };
|
||||||
|
static const wchar_t *kRouterDllName { L"MPR.dll" };
|
||||||
|
|
||||||
struct WIN32_MEMORY_RANGE_ENTRY2
|
struct WIN32_MEMORY_RANGE_ENTRY2
|
||||||
{
|
{
|
||||||
@ -87,6 +93,18 @@ namespace Aurora
|
|||||||
PVOID Address
|
PVOID Address
|
||||||
);
|
);
|
||||||
|
|
||||||
|
inline NTSTATUS(__stdcall *pNtQuerySymbolicLinkObject)(
|
||||||
|
HANDLE LinkHandle,
|
||||||
|
PUNICODE_STRING LinkTarget,
|
||||||
|
PULONG ReturnedLength
|
||||||
|
);
|
||||||
|
|
||||||
|
inline NTSTATUS(__stdcall *pNtOpenSymbolicLinkObject)(
|
||||||
|
PHANDLE LinkHandle,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes
|
||||||
|
);
|
||||||
|
|
||||||
inline DWORD(__stdcall *pNtDelayExecution)(
|
inline DWORD(__stdcall *pNtDelayExecution)(
|
||||||
BOOLEAN Alertable,
|
BOOLEAN Alertable,
|
||||||
PLARGE_INTEGER DelayInterval
|
PLARGE_INTEGER DelayInterval
|
||||||
@ -750,6 +768,73 @@ namespace Aurora
|
|||||||
HANDLE hData
|
HANDLE hData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// SETUPAPI.dll
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetupDiEnumDeviceInterfaces)(
|
||||||
|
PVOID DeviceInfoSet,
|
||||||
|
_SP_DEVINFO_DATA * DeviceInfoData,
|
||||||
|
const GUID * InterfaceClassGuid,
|
||||||
|
DWORD MemberIndex,
|
||||||
|
_SP_DEVICE_INTERFACE_DATA * DeviceInterfaceData
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetupDiDestroyDeviceInfoList)(
|
||||||
|
PVOID DeviceInfoSet
|
||||||
|
);
|
||||||
|
|
||||||
|
inline PVOID(__stdcall *pSetupDiGetClassDevsW)(
|
||||||
|
const GUID * ClassGuid,
|
||||||
|
PCWSTR Enumerator,
|
||||||
|
HWND hwndParent,
|
||||||
|
DWORD Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetupDiGetDeviceRegistryPropertyA)(
|
||||||
|
PVOID DeviceInfoSet,
|
||||||
|
_SP_DEVINFO_DATA * DeviceInfoData,
|
||||||
|
DWORD Property,
|
||||||
|
PDWORD PropertyRegDataType,
|
||||||
|
PBYTE PropertyBuffer,
|
||||||
|
DWORD PropertyBufferSize,
|
||||||
|
PDWORD RequiredSize
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetupDiGetDeviceInterfaceDetailW)(
|
||||||
|
PVOID DeviceInfoSet,
|
||||||
|
_SP_DEVICE_INTERFACE_DATA * DeviceInterfaceData,
|
||||||
|
_SP_DEVICE_INTERFACE_DETAIL_DATA_W * DeviceInterfaceDetailData,
|
||||||
|
DWORD DeviceInterfaceDetailDataSize,
|
||||||
|
PDWORD RequiredSize,
|
||||||
|
_SP_DEVINFO_DATA * DeviceInfoData
|
||||||
|
);
|
||||||
|
|
||||||
|
// MPR.dll
|
||||||
|
inline DWORD(__stdcall *pWNetCloseEnum)(
|
||||||
|
HANDLE hEnum
|
||||||
|
);
|
||||||
|
|
||||||
|
inline DWORD(__stdcall *pWNetEnumResourceW)(
|
||||||
|
HANDLE hEnum,
|
||||||
|
LPDWORD lpcCount,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
LPDWORD lpBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
inline DWORD(__stdcall *pWNetOpenEnumW)(
|
||||||
|
DWORD dwScope,
|
||||||
|
DWORD dwType,
|
||||||
|
DWORD dwUsage,
|
||||||
|
_NETRESOURCEW * lpNetResource,
|
||||||
|
LPHANDLE lphEnum
|
||||||
|
);
|
||||||
|
|
||||||
|
inline DWORD(__stdcall *pWNetGetUniversalNameW)(
|
||||||
|
LPCWSTR lpLocalPath,
|
||||||
|
DWORD dwInfoLevel,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
LPDWORD lpBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
inline bool gUseNativeWaitMutex {};
|
inline bool gUseNativeWaitMutex {};
|
||||||
inline bool gUseNativeWaitCondvar {};
|
inline bool gUseNativeWaitCondvar {};
|
||||||
inline bool gUseNativeWaitSemapahore {};
|
inline bool gUseNativeWaitSemapahore {};
|
||||||
|
1073
Source/IO/FS/FSPlatformDevices.NT.cpp
Normal file
1073
Source/IO/FS/FSPlatformDevices.NT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
14
Source/IO/FS/FSPlatformDevices.NT.hpp
Normal file
14
Source/IO/FS/FSPlatformDevices.NT.hpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: FSPlatformDevices.NT.hpp
|
||||||
|
Date: 2023-08-11
|
||||||
|
Date: 2023-12-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
125
Source/IO/FS/FSPlatformDevices.cpp
Normal file
125
Source/IO/FS/FSPlatformDevices.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: FSPlatformDevices.cpp
|
||||||
|
Date: 2023-08-11
|
||||||
|
Date: 2023-12-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <Source/RuntimeInternal.hpp>
|
||||||
|
#include "FS.hpp"
|
||||||
|
#include "FSPlatformDevices.hpp"
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
void InitPlatformFSCacheAtLoad()
|
||||||
|
{
|
||||||
|
static AuInitOnce gInitOnce;
|
||||||
|
|
||||||
|
gInitOnce.Call([]()
|
||||||
|
{
|
||||||
|
ResetDeviceCache();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuResult<AuString> GetDeviceModel(const AuString &physicalDevicePath)
|
||||||
|
{
|
||||||
|
InitPlatformFSCacheAtLoad();
|
||||||
|
|
||||||
|
AU_LOCK_GUARD(gFSDirMutex);
|
||||||
|
for (const auto &refFSDevice : gCachedDevices)
|
||||||
|
{
|
||||||
|
if (refFSDevice.devicePath == physicalDevicePath)
|
||||||
|
{
|
||||||
|
auto copy = refFSDevice.productModel;
|
||||||
|
return AuMove(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuResult<FSDevice> GetFSDeviceByFilePath(const AuString &path)
|
||||||
|
{
|
||||||
|
AuList<AuPair<AuUInt, const FSDevice *>> devs;
|
||||||
|
|
||||||
|
InitPlatformFSCacheAtLoad();
|
||||||
|
|
||||||
|
auto normalized = AuFS::NormalizePathRet(path);
|
||||||
|
if (normalized.empty())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gFSDirMutex);
|
||||||
|
|
||||||
|
for (const auto &refFSDevice : gCachedDevices)
|
||||||
|
{
|
||||||
|
for (const auto &refPart : refFSDevice.partitions) // todo sort
|
||||||
|
{
|
||||||
|
for (const auto &refMnt : refPart.filesystemMountPoints) // todo sort
|
||||||
|
{
|
||||||
|
if (AuStartsWith(path, refMnt))
|
||||||
|
{
|
||||||
|
devs.push_back(AuMakePair(refMnt.size(), &refFSDevice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devs.empty())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(devs.begin(),
|
||||||
|
devs.end(),
|
||||||
|
[](AuPair<AuUInt, const FSDevice *> a, AuPair<AuUInt, const FSDevice *> b)
|
||||||
|
{
|
||||||
|
return AuGet<0>(a) > AuGet<0>(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto copy = AuGet<1>(devs[0]);
|
||||||
|
return AuMove(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuList<FSDevice> GetFSDevices()
|
||||||
|
{
|
||||||
|
InitPlatformFSCacheAtLoad();
|
||||||
|
AU_LOCK_GUARD(gFSDirMutex);
|
||||||
|
return gCachedDevices;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuResult<FSDevice> GetFSDeviceByDevice(const AuString &physicalDevicePath)
|
||||||
|
{
|
||||||
|
InitPlatformFSCacheAtLoad();
|
||||||
|
|
||||||
|
AU_LOCK_GUARD(gFSDirMutex);
|
||||||
|
for (const auto &refFSDevice : gCachedDevices)
|
||||||
|
{
|
||||||
|
if (refFSDevice.devicePath == physicalDevicePath)
|
||||||
|
{
|
||||||
|
auto copy = refFSDevice;
|
||||||
|
return AuMove(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM const AuList<FSDevice> &GetFSDevicesCachedUnsafe()
|
||||||
|
{
|
||||||
|
InitPlatformFSCacheAtLoad();
|
||||||
|
return gCachedDevices;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuList<FSDevice> SysGetFSDevices();
|
||||||
|
|
||||||
|
AUKN_SYM void ResetDeviceCache()
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gFSDirMutex);
|
||||||
|
gCachedDevices = AuMove(SysGetFSDevices());
|
||||||
|
}
|
||||||
|
}
|
17
Source/IO/FS/FSPlatformDevices.hpp
Normal file
17
Source/IO/FS/FSPlatformDevices.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: FSPlatformDevices.hpp
|
||||||
|
Date: 2023-08-11
|
||||||
|
Date: 2023-12-05
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Aurora/IO/FS/Devices.hpp>
|
||||||
|
|
||||||
|
namespace Aurora::IO::FS
|
||||||
|
{
|
||||||
|
inline AuList<FSDevice> gCachedDevices;
|
||||||
|
inline AuThreadPrimitives::CriticalSection gFSDirMutex;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user