mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 09:22:57 -05:00
ARM64: initial port
This commit is contained in:
@ -32,24 +32,17 @@ static BOOLEAN FspMountDoNotUseLauncher;
|
||||
|
||||
static VOID FspMountInitializeFromRegistry(VOID)
|
||||
{
|
||||
HKEY RegKey;
|
||||
LONG Result;
|
||||
DWORD Size;
|
||||
DWORD MountDoNotUseLauncher;
|
||||
DWORD Size;
|
||||
LONG Result;
|
||||
|
||||
MountDoNotUseLauncher = 0;
|
||||
|
||||
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\" FSP_FSCTL_PRODUCT_NAME,
|
||||
0, KEY_READ | KEY_WOW64_32KEY, &RegKey);
|
||||
Size = sizeof MountDoNotUseLauncher;
|
||||
Result = RegGetValueW(HKEY_LOCAL_MACHINE, L"" FSP_FSCTL_PRODUCT_FULL_REGKEY,
|
||||
L"MountDoNotUseLauncher",
|
||||
RRF_RT_REG_DWORD, 0, &MountDoNotUseLauncher, &Size);
|
||||
if (ERROR_SUCCESS == Result)
|
||||
{
|
||||
Size = sizeof MountDoNotUseLauncher;
|
||||
Result = RegGetValueW(RegKey, 0, L"MountDoNotUseLauncher",
|
||||
RRF_RT_REG_DWORD, 0, &MountDoNotUseLauncher, &Size);
|
||||
RegCloseKey(RegKey);
|
||||
}
|
||||
|
||||
FspMountDoNotUseLauncher = !!MountDoNotUseLauncher;
|
||||
FspMountDoNotUseLauncher = !!MountDoNotUseLauncher;
|
||||
}
|
||||
|
||||
static BOOL WINAPI FspMountInitialize(
|
||||
|
@ -1433,18 +1433,30 @@ namespace Fsp.Interop
|
||||
internal static String ProductFileName = "winfsp";
|
||||
private static IntPtr LoadDll()
|
||||
{
|
||||
String DllPath = null;
|
||||
String DllName = 8 == IntPtr.Size ?
|
||||
ProductFileName + "-x64.dll" :
|
||||
ProductFileName + "-x86.dll";
|
||||
String KeyName = 8 == IntPtr.Size ?
|
||||
"HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\" + ProductName :
|
||||
"HKEY_LOCAL_MACHINE\\Software\\" + ProductName;
|
||||
String RegPath, DllName, DllPath;
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo(out SystemInfo);
|
||||
switch ((UInt32)SystemInfo.wProcessorArchitecture)
|
||||
{
|
||||
case SYSTEM_INFO.PROCESSOR_ARCHITECTURE_ARM64:
|
||||
RegPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\" + ProductName;
|
||||
DllName = ProductFileName + "-a64.dll";
|
||||
break;
|
||||
case SYSTEM_INFO.PROCESSOR_ARCHITECTURE_AMD64:
|
||||
RegPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\" + ProductName;
|
||||
DllName = ProductFileName + "-x64.dll";
|
||||
break;
|
||||
case SYSTEM_INFO.PROCESSOR_ARCHITECTURE_INTEL:
|
||||
default:
|
||||
RegPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\" + ProductName;
|
||||
DllName = ProductFileName + "-x86.dll";
|
||||
break;
|
||||
}
|
||||
IntPtr Module;
|
||||
Module = LoadLibraryW(DllName);
|
||||
if (IntPtr.Zero == Module)
|
||||
{
|
||||
DllPath = Microsoft.Win32.Registry.GetValue(KeyName, "InstallDir", null) as String;
|
||||
DllPath = Microsoft.Win32.Registry.GetValue(RegPath, "InstallDir", null) as String;
|
||||
if (null != DllPath)
|
||||
{
|
||||
DllPath = Path.Combine(DllPath, Path.Combine("bin", DllName));
|
||||
@ -1546,6 +1558,39 @@ namespace Fsp.Interop
|
||||
CheckVersion();
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SYSTEM_INFO
|
||||
{
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_INTEL = 0;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_MIPS = 1;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_ALPHA = 2;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_PPC = 3;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_SHX = 4;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_ARM = 5;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_IA64 = 6;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_ALPHA64 = 7;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_MSIL = 8;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_AMD64 = 9;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 = 10;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_NEUTRAL = 11;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_ARM64 = 12;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 = 13;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 = 14;
|
||||
internal const UInt32 PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;
|
||||
|
||||
internal UInt16 wProcessorArchitecture;
|
||||
internal UInt16 wReserved;
|
||||
internal UInt32 dwPageSize;
|
||||
internal IntPtr lpMinimumApplicationAddress;
|
||||
internal IntPtr lpMaximumApplicationAddress;
|
||||
internal IntPtr dwActiveProcessorMask;
|
||||
internal UInt32 dwNumberOfProcessors;
|
||||
internal UInt32 dwProcessorType;
|
||||
internal UInt32 dwAllocationGranularity;
|
||||
internal UInt16 wProcessorLevel;
|
||||
internal UInt16 wProcessorRevision;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||
private static extern IntPtr LoadLibraryW(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] String DllName);
|
||||
@ -1553,6 +1598,9 @@ namespace Fsp.Interop
|
||||
private static extern IntPtr GetProcAddress(
|
||||
IntPtr hModule,
|
||||
[MarshalAs(UnmanagedType.LPStr)] String lpProcName);
|
||||
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = false)]
|
||||
private static extern void GetSystemInfo(
|
||||
out SYSTEM_INFO SystemInfo);
|
||||
[DllImport("advapi32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern UInt32 GetSecurityDescriptorLength(IntPtr SecurityDescriptor);
|
||||
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||
|
@ -174,24 +174,17 @@ exit:
|
||||
|
||||
static VOID FspPosixInitializeFromRegistry(VOID)
|
||||
{
|
||||
HKEY RegKey;
|
||||
LONG Result;
|
||||
DWORD Size;
|
||||
DWORD DistinctPermsForSameOwnerGroup;
|
||||
DWORD Size;
|
||||
LONG Result;
|
||||
|
||||
DistinctPermsForSameOwnerGroup = 0;
|
||||
|
||||
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\" FSP_FSCTL_PRODUCT_NAME,
|
||||
0, KEY_READ | KEY_WOW64_32KEY, &RegKey);
|
||||
Size = sizeof DistinctPermsForSameOwnerGroup;
|
||||
Result = RegGetValueW(HKEY_LOCAL_MACHINE, L"" FSP_FSCTL_PRODUCT_FULL_REGKEY,
|
||||
L"DistinctPermsForSameOwnerGroup",
|
||||
RRF_RT_REG_DWORD, 0, &DistinctPermsForSameOwnerGroup, &Size);
|
||||
if (ERROR_SUCCESS == Result)
|
||||
{
|
||||
Size = sizeof DistinctPermsForSameOwnerGroup;
|
||||
Result = RegGetValueW(RegKey, 0, L"DistinctPermsForSameOwnerGroup",
|
||||
RRF_RT_REG_DWORD, 0, &DistinctPermsForSameOwnerGroup, &Size);
|
||||
RegCloseKey(RegKey);
|
||||
}
|
||||
|
||||
FspDistinctPermsForSameOwnerGroup = !!DistinctPermsForSameOwnerGroup;
|
||||
FspDistinctPermsForSameOwnerGroup = !!DistinctPermsForSameOwnerGroup;
|
||||
}
|
||||
|
||||
static BOOL WINAPI FspPosixInitialize(
|
||||
|
@ -442,13 +442,13 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||
|
||||
/* initialize our timer routine and start our expiration timer */
|
||||
#pragma prefast(suppress:28133, "We are a filesystem: we do not have AddDevice")
|
||||
Result = IoInitializeTimer(DeviceObject, FspFsvolDeviceTimerRoutine, 0);
|
||||
Result = FspDeviceInitializeTimer(DeviceObject, FspFsvolDeviceTimerRoutine, 0);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
KeInitializeSpinLock(&FsvolDeviceExtension->ExpirationLock);
|
||||
ExInitializeWorkItem(&FsvolDeviceExtension->ExpirationWorkItem,
|
||||
FspFsvolDeviceExpirationRoutine, DeviceObject);
|
||||
IoStartTimer(DeviceObject);
|
||||
FspDeviceStartTimer(DeviceObject);
|
||||
FsvolDeviceExtension->InitDoneTimer = 1;
|
||||
|
||||
/* initialize the volume information */
|
||||
@ -472,7 +472,7 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
|
||||
* references our DeviceObject before queueing work items.
|
||||
*/
|
||||
if (FsvolDeviceExtension->InitDoneTimer)
|
||||
IoStopTimer(DeviceObject);
|
||||
FspDeviceStopTimer(DeviceObject);
|
||||
|
||||
/* delete the file system statistics */
|
||||
if (FsvolDeviceExtension->InitDoneStat)
|
||||
|
124
src/sys/devtimer.c
Normal file
124
src/sys/devtimer.c
Normal file
@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @file sys/devtimer.c
|
||||
*
|
||||
* @copyright 2015-2021 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.
|
||||
*/
|
||||
|
||||
#include <sys/driver.h>
|
||||
|
||||
/*
|
||||
* IoTimer Emulation.
|
||||
*
|
||||
* This is required because IoInitializeTimer and friends is missing from Windows on ARM64.
|
||||
*/
|
||||
|
||||
static LIST_ENTRY FspDeviceTimerList;
|
||||
static KSPIN_LOCK FspDeviceTimerLock;
|
||||
static KDPC FspDeviceTimerDpc;
|
||||
static KTIMER FspDeviceTimer;
|
||||
|
||||
static KDEFERRED_ROUTINE FspDeviceTimerRoutine;
|
||||
|
||||
NTSTATUS FspDeviceInitializeAllTimers(VOID)
|
||||
{
|
||||
LARGE_INTEGER DueTime;
|
||||
LONG Period;
|
||||
|
||||
InitializeListHead(&FspDeviceTimerList);
|
||||
KeInitializeSpinLock(&FspDeviceTimerLock);
|
||||
|
||||
KeInitializeDpc(&FspDeviceTimerDpc, FspDeviceTimerRoutine, 0);
|
||||
KeInitializeTimerEx(&FspDeviceTimer, SynchronizationTimer);
|
||||
|
||||
DueTime.QuadPart = 1000/*ms*/ * -10000;
|
||||
Period = 1000/*ms*/;
|
||||
KeSetTimerEx(&FspDeviceTimer, DueTime, Period, &FspDeviceTimerDpc);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID FspDeviceFinalizeAllTimers(VOID)
|
||||
{
|
||||
KeCancelTimer(&FspDeviceTimer);
|
||||
|
||||
#if DBG
|
||||
KIRQL Irql;
|
||||
KeAcquireSpinLock(&FspDeviceTimerLock, &Irql);
|
||||
ASSERT(IsListEmpty(&FspDeviceTimerList));
|
||||
KeReleaseSpinLock(&FspDeviceTimerLock, Irql);
|
||||
#endif
|
||||
}
|
||||
|
||||
static VOID FspDeviceTimerRoutine(
|
||||
PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
FSP_DEVICE_TIMER *Timer;
|
||||
PLIST_ENTRY ListEntry;
|
||||
KIRQL Irql;
|
||||
|
||||
KeAcquireSpinLock(&FspDeviceTimerLock, &Irql);
|
||||
for (ListEntry = FspDeviceTimerList.Flink;
|
||||
&FspDeviceTimerList != ListEntry;
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
Timer = CONTAINING_RECORD(ListEntry, FSP_DEVICE_TIMER, ListEntry);
|
||||
Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
|
||||
}
|
||||
KeReleaseSpinLock(&FspDeviceTimerLock, Irql);
|
||||
}
|
||||
|
||||
NTSTATUS FspDeviceInitializeTimer(PDEVICE_OBJECT DeviceObject,
|
||||
PIO_TIMER_ROUTINE TimerRoutine, PVOID Context)
|
||||
{
|
||||
FSP_DEVICE_EXTENSION *DeviceExtension;
|
||||
|
||||
DeviceExtension = FspDeviceExtension(DeviceObject);
|
||||
|
||||
DeviceExtension->DeviceTimer.TimerRoutine = TimerRoutine;
|
||||
DeviceExtension->DeviceTimer.DeviceObject = DeviceObject;
|
||||
DeviceExtension->DeviceTimer.Context = Context;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID FspDeviceStartTimer(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
FSP_DEVICE_EXTENSION *DeviceExtension;
|
||||
KIRQL Irql;
|
||||
|
||||
DeviceExtension = FspDeviceExtension(DeviceObject);
|
||||
|
||||
KeAcquireSpinLock(&FspDeviceTimerLock, &Irql);
|
||||
InsertTailList(&FspDeviceTimerList, &DeviceExtension->DeviceTimer.ListEntry);
|
||||
KeReleaseSpinLock(&FspDeviceTimerLock, Irql);
|
||||
}
|
||||
|
||||
VOID FspDeviceStopTimer(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
FSP_DEVICE_EXTENSION *DeviceExtension;
|
||||
KIRQL Irql;
|
||||
|
||||
DeviceExtension = FspDeviceExtension(DeviceObject);
|
||||
|
||||
KeAcquireSpinLock(&FspDeviceTimerLock, &Irql);
|
||||
RemoveEntryList(&DeviceExtension->DeviceTimer.ListEntry);
|
||||
KeReleaseSpinLock(&FspDeviceTimerLock, Irql);
|
||||
}
|
@ -123,7 +123,7 @@ NTSTATUS DriverEntry(
|
||||
DriverObject->FastIoDispatch = &FspFastIoDispatch;
|
||||
|
||||
BOOLEAN InitDoneGRes = FALSE, InitDoneSilo = FALSE, InitDonePsBuf = FALSE,
|
||||
InitDoneDevices = FALSE;
|
||||
InitDoneTimers = FALSE, InitDoneDevices = FALSE;
|
||||
|
||||
FspDriverObject = DriverObject;
|
||||
FspDriverMultiVersionInitialize();
|
||||
@ -141,6 +141,11 @@ NTSTATUS DriverEntry(
|
||||
goto exit;
|
||||
InitDonePsBuf = TRUE;
|
||||
|
||||
Result = FspDeviceInitializeAllTimers();
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
InitDoneTimers = TRUE;
|
||||
|
||||
Result = FspDriverInitializeDevices();
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
@ -153,6 +158,8 @@ exit:
|
||||
{
|
||||
if (InitDoneDevices)
|
||||
FspDriverFinalizeDevices();
|
||||
if (InitDoneTimers)
|
||||
FspDeviceFinalizeAllTimers();
|
||||
if (InitDonePsBuf)
|
||||
FspProcessBufferFinalize();
|
||||
if (InitDoneSilo)
|
||||
|
@ -1117,6 +1117,13 @@ enum
|
||||
FspFsvolDeviceEaCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE),
|
||||
};
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PIO_TIMER_ROUTINE TimerRoutine;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PVOID Context;
|
||||
} FSP_DEVICE_TIMER;
|
||||
typedef struct
|
||||
{
|
||||
PUNICODE_STRING FileName;
|
||||
PVOID Context;
|
||||
@ -1144,6 +1151,8 @@ typedef struct
|
||||
LONG RefCount;
|
||||
UINT32 Kind;
|
||||
GUID SiloContainerId;
|
||||
/* IoTimer emulation */
|
||||
FSP_DEVICE_TIMER DeviceTimer;
|
||||
} FSP_DEVICE_EXTENSION;
|
||||
typedef struct
|
||||
{
|
||||
@ -1295,6 +1304,12 @@ NTSTATUS FspDeviceCopyList(
|
||||
VOID FspDeviceDeleteList(
|
||||
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
||||
VOID FspDeviceDeleteAll(VOID);
|
||||
NTSTATUS FspDeviceInitializeAllTimers(VOID);
|
||||
VOID FspDeviceFinalizeAllTimers(VOID);
|
||||
NTSTATUS FspDeviceInitializeTimer(PDEVICE_OBJECT DeviceObject,
|
||||
PIO_TIMER_ROUTINE TimerRoutine, PVOID Context);
|
||||
VOID FspDeviceStartTimer(PDEVICE_OBJECT DeviceObject);
|
||||
VOID FspDeviceStopTimer(PDEVICE_OBJECT DeviceObject);
|
||||
static inline
|
||||
VOID FspDeviceGlobalLock(VOID)
|
||||
{
|
||||
|
Reference in New Issue
Block a user