mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-07 20:42:09 -05:00
sys, dll: NetworkProvider implementation (NPGetConnection)
This commit is contained in:
parent
c40ce93fe2
commit
1bcd3cec0a
@ -24,6 +24,7 @@
|
|||||||
<ClInclude Include="..\..\src\dll\library.h" />
|
<ClInclude Include="..\..\src\dll\library.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\dll\np.c" />
|
||||||
<ClCompile Include="..\..\src\dll\security.c" />
|
<ClCompile Include="..\..\src\dll\security.c" />
|
||||||
<ClCompile Include="..\..\src\dll\debug.c" />
|
<ClCompile Include="..\..\src\dll\debug.c" />
|
||||||
<ClCompile Include="..\..\src\dll\fsctl.c" />
|
<ClCompile Include="..\..\src\dll\fsctl.c" />
|
||||||
@ -34,6 +35,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\path.c" />
|
<ClCompile Include="..\..\src\dll\path.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="..\..\src\dll\library.def" />
|
||||||
<None Include="..\..\src\dll\ntstatus.i" />
|
<None Include="..\..\src\dll\ntstatus.i" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
@ -133,6 +135,7 @@
|
|||||||
<GenerateMapFile>true</GenerateMapFile>
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@ -156,6 +159,7 @@
|
|||||||
<GenerateMapFile>true</GenerateMapFile>
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@ -182,6 +186,7 @@
|
|||||||
<GenerateMapFile>true</GenerateMapFile>
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@ -208,6 +213,7 @@
|
|||||||
<GenerateMapFile>true</GenerateMapFile>
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
@ -49,10 +49,16 @@
|
|||||||
<ClCompile Include="..\..\src\dll\security.c">
|
<ClCompile Include="..\..\src\dll\security.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\dll\np.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\dll\ntstatus.i">
|
<None Include="..\..\src\dll\ntstatus.i">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="..\..\src\dll\library.def">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -34,6 +34,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
|||||||
/* fsctl device codes */
|
/* fsctl device codes */
|
||||||
#define FSP_FSCTL_VOLUME_NAME \
|
#define FSP_FSCTL_VOLUME_NAME \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define FSP_FSCTL_VOLUME_LIST \
|
||||||
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'L', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_TRANSACT \
|
#define FSP_FSCTL_TRANSACT \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_TRANSACT_BATCH \
|
#define FSP_FSCTL_TRANSACT_BATCH \
|
||||||
@ -405,6 +407,8 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
|||||||
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
||||||
BOOLEAN Batch);
|
BOOLEAN Batch);
|
||||||
FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle);
|
FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle);
|
||||||
|
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
||||||
|
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -119,3 +119,58 @@ FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle)
|
|||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
||||||
|
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWSTR DeviceRoot;
|
||||||
|
SIZE_T DeviceRootSize, DevicePathSize;
|
||||||
|
WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr;
|
||||||
|
HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD Bytes;
|
||||||
|
|
||||||
|
/* check lengths; everything must fit within MAX_PATH */
|
||||||
|
DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\";
|
||||||
|
DeviceRootSize = lstrlenW(DeviceRoot) * sizeof(WCHAR);
|
||||||
|
DevicePathSize = lstrlenW(DevicePath) * sizeof(WCHAR);
|
||||||
|
if (DeviceRootSize + DevicePathSize + sizeof(WCHAR) > sizeof DevicePathBuf)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* prepare the device path to be opened */
|
||||||
|
DevicePathPtr = DevicePathBuf;
|
||||||
|
memcpy(DevicePathPtr, DeviceRoot, DeviceRootSize);
|
||||||
|
DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DeviceRootSize);
|
||||||
|
memcpy(DevicePathPtr, DevicePath, DevicePathSize);
|
||||||
|
DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DevicePathSize);
|
||||||
|
*DevicePathPtr = L'\0';
|
||||||
|
|
||||||
|
VolumeHandle = CreateFileW(DevicePathBuf,
|
||||||
|
0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
||||||
|
if (INVALID_HANDLE_VALUE == VolumeHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
if (STATUS_OBJECT_PATH_NOT_FOUND == Result ||
|
||||||
|
STATUS_OBJECT_NAME_NOT_FOUND == Result)
|
||||||
|
Result = STATUS_NO_SUCH_DEVICE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_VOLUME_LIST,
|
||||||
|
0, 0,
|
||||||
|
VolumeListBuf, (DWORD)*PVolumeListSize,
|
||||||
|
&Bytes, 0))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*PVolumeListSize = Bytes;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != VolumeHandle)
|
||||||
|
CloseHandle(VolumeHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
|
||||||
|
HINSTANCE DllInstance;
|
||||||
HANDLE ProcessHeap;
|
HANDLE ProcessHeap;
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
||||||
@ -13,6 +14,7 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
|||||||
switch (Reason)
|
switch (Reason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
DllInstance = Instance;
|
||||||
ProcessHeap = GetProcessHeap();
|
ProcessHeap = GetProcessHeap();
|
||||||
if (0 == ProcessHeap)
|
if (0 == ProcessHeap)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -33,3 +35,21 @@ BOOL WINAPI _DllMainCRTStartup(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
|||||||
return DllMain(Instance, Reason, Reserved);
|
return DllMain(Instance, Reason, Reserved);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI DllRegisterServer(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspNpRegister();
|
||||||
|
|
||||||
|
return NT_SUCCESS(Result) ? S_OK : 0x80040201/*SELFREG_E_CLASS*/;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI DllUnregisterServer(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspNpUnregister();
|
||||||
|
|
||||||
|
return NT_SUCCESS(Result) ? S_OK : 0x80040201/*SELFREG_E_CLASS*/;
|
||||||
|
}
|
||||||
|
5
src/dll/library.def
Normal file
5
src/dll/library.def
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
EXPORTS
|
||||||
|
DllRegisterServer PRIVATE
|
||||||
|
DllUnregisterServer PRIVATE
|
||||||
|
NPGetCaps PRIVATE
|
||||||
|
NPGetConnection PRIVATE
|
@ -95,4 +95,7 @@ BOOLEAN RemoveEntryList(PLIST_ENTRY Entry)
|
|||||||
VOID FspFileSystemInitialize(VOID);
|
VOID FspFileSystemInitialize(VOID);
|
||||||
VOID FspFileSystemFinalize(VOID);
|
VOID FspFileSystemFinalize(VOID);
|
||||||
|
|
||||||
|
NTSTATUS FspNpRegister(VOID);
|
||||||
|
NTSTATUS FspNpUnregister(VOID);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
351
src/dll/np.c
Normal file
351
src/dll/np.c
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
/**
|
||||||
|
* @file dll/np.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dll/library.h>
|
||||||
|
#include <npapi.h>
|
||||||
|
|
||||||
|
#define FSP_NP_NAME "WinFsp.Np"
|
||||||
|
#define FSP_NP_DESC "File System Proxy"
|
||||||
|
#define FSP_NP_TYPE ' spF' /* pick a value hopefully not in use */
|
||||||
|
|
||||||
|
DWORD APIENTRY NPGetCaps(DWORD Index)
|
||||||
|
{
|
||||||
|
switch (Index)
|
||||||
|
{
|
||||||
|
case WNNC_ADMIN:
|
||||||
|
/*
|
||||||
|
* WNNC_ADM_DIRECTORYNOTIFY
|
||||||
|
* WNNC_ADM_GETDIRECTORYTYPE
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
case WNNC_CONNECTION:
|
||||||
|
/*
|
||||||
|
* WNNC_CON_ADDCONECTION
|
||||||
|
* WNNC_CON_CANCELCONNECTION
|
||||||
|
* WNNC_CON_GETCONNECTIONS
|
||||||
|
* WNNC_CON_ADDCONECTION3
|
||||||
|
* WNNC_CON_GETPERFORMANCE
|
||||||
|
* WNNC_CON_DEFER
|
||||||
|
*/
|
||||||
|
return WNNC_CON_GETCONNECTIONS;
|
||||||
|
case WNNC_DIALOG:
|
||||||
|
/*
|
||||||
|
* WNNC_DLG_DEVICEMODE
|
||||||
|
* WNNC_DLG_FORMATNETNAME
|
||||||
|
* WNNC_DLG_GETRESOURCEINFORMATION
|
||||||
|
* WNNC_DLG_GETRESOURCEPARENT
|
||||||
|
* WNNC_DLG_PERMISSIONEDITOR
|
||||||
|
* WNNC_DLG_PROPERTYDIALOG
|
||||||
|
* WNNC_DLG_SEARCHDIALOG
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
case WNNC_ENUMERATION:
|
||||||
|
/*
|
||||||
|
* WNNC_ENUM_GLOBAL
|
||||||
|
* WNNC_ENUM_LOCAL
|
||||||
|
* WNNC_ENUM_CONTEXT
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
case WNNC_NET_TYPE:
|
||||||
|
return FSP_NP_TYPE;
|
||||||
|
case WNNC_SPEC_VERSION:
|
||||||
|
return WNNC_SPEC_VERSION51;
|
||||||
|
case WNNC_START:
|
||||||
|
return 1;
|
||||||
|
case WNNC_USER:
|
||||||
|
/*
|
||||||
|
* WNNC_USR_GETUSER
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspNpGetVolumeList(
|
||||||
|
PWCHAR *PVolumeListBuf, PSIZE_T PVolumeListSize)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWCHAR VolumeListBuf;
|
||||||
|
SIZE_T VolumeListSize;
|
||||||
|
|
||||||
|
*PVolumeListBuf = 0;
|
||||||
|
*PVolumeListSize = 0;
|
||||||
|
|
||||||
|
for (VolumeListSize = 1024;; VolumeListSize *= 2)
|
||||||
|
{
|
||||||
|
VolumeListBuf = MemAlloc(VolumeListSize);
|
||||||
|
if (0 == VolumeListBuf)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
Result = FspFsctlGetVolumeList(L"" FSP_FSCTL_NET_DEVICE_NAME,
|
||||||
|
VolumeListBuf, &VolumeListSize);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
*PVolumeListBuf = VolumeListBuf;
|
||||||
|
*PVolumeListSize = VolumeListSize;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemFree(VolumeListBuf);
|
||||||
|
|
||||||
|
if (STATUS_BUFFER_TOO_SMALL != Result)
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY NPGetConnection(LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnBufferLen)
|
||||||
|
{
|
||||||
|
DWORD NpResult;
|
||||||
|
NTSTATUS Result;
|
||||||
|
WCHAR LocalNameBuf[3];
|
||||||
|
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)];
|
||||||
|
PWCHAR VolumeListBuf = 0, VolumeListBufEnd, VolumeName, P;
|
||||||
|
SIZE_T VolumeListSize, VolumeNameSize;
|
||||||
|
ULONG Backslashes;
|
||||||
|
|
||||||
|
if (0 == lpLocalName ||
|
||||||
|
!(
|
||||||
|
(L'A' <= lpLocalName[0] && lpLocalName[0] <= L'Z') ||
|
||||||
|
(L'a' <= lpLocalName[0] && lpLocalName[0] <= L'z')
|
||||||
|
) ||
|
||||||
|
L':' != lpLocalName[1])
|
||||||
|
return WN_BAD_LOCALNAME;
|
||||||
|
|
||||||
|
LocalNameBuf[0] = lpLocalName[0];
|
||||||
|
LocalNameBuf[1] = L':';
|
||||||
|
LocalNameBuf[2] = L'\0';
|
||||||
|
|
||||||
|
if (0 == QueryDosDeviceW(LocalNameBuf, VolumeNameBuf, sizeof VolumeNameBuf))
|
||||||
|
return WN_NOT_CONNECTED;
|
||||||
|
|
||||||
|
Result = FspNpGetVolumeList(&VolumeListBuf, &VolumeListSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return WN_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
NpResult = WN_NOT_CONNECTED;
|
||||||
|
for (P = VolumeListBuf, VolumeListBufEnd = (PVOID)((PUINT8)P + VolumeListSize), VolumeName = P;
|
||||||
|
VolumeListBufEnd > P; P++)
|
||||||
|
{
|
||||||
|
if (L'\0' == *P)
|
||||||
|
{
|
||||||
|
if (0 == lstrcmpW(VolumeNameBuf, VolumeName))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Looks like this is a WinFsp device. Extract the VolumePrefix from the VolumeName.
|
||||||
|
*
|
||||||
|
* The VolumeName will have the following syntax:
|
||||||
|
* \Device\Volume{GUID}\Server\Share
|
||||||
|
*
|
||||||
|
* We want to extract the \Server\Share part. We will simply count backslashes and
|
||||||
|
* stop at the third one. Since we are about to break this loop, it is ok to mess
|
||||||
|
* with the loop variables.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (Backslashes = 0; VolumeName < P; VolumeName++)
|
||||||
|
if (L'\\' == *VolumeName)
|
||||||
|
if (3 == ++Backslashes)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (3 == Backslashes)
|
||||||
|
{
|
||||||
|
VolumeNameSize = lstrlenW(VolumeName) + 1/* term-0 */;
|
||||||
|
if (*lpnBufferLen >= 1/* lead-\ */ + VolumeNameSize)
|
||||||
|
{
|
||||||
|
*lpRemoteName = L'\\';
|
||||||
|
memcpy(lpRemoteName + 1, VolumeName, VolumeNameSize * sizeof(WCHAR));
|
||||||
|
NpResult = WN_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*lpnBufferLen = (DWORD)(1/* lead-\ */ + VolumeNameSize);
|
||||||
|
NpResult = WN_MORE_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
VolumeName = P + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MemFree(VolumeListBuf);
|
||||||
|
|
||||||
|
return NpResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspNpRegister(VOID)
|
||||||
|
{
|
||||||
|
extern HINSTANCE DllInstance;
|
||||||
|
WCHAR ProviderPath[MAX_PATH];
|
||||||
|
WCHAR RegBuffer[1024];
|
||||||
|
PWSTR P, Part;
|
||||||
|
DWORD RegResult, RegType, RegBufferSize;
|
||||||
|
HKEY RegKey;
|
||||||
|
BOOLEAN FoundProvider;
|
||||||
|
|
||||||
|
if (0 == GetModuleFileNameW(DllInstance, ProviderPath, MAX_PATH))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
RegResult = RegCreateKeyExW(
|
||||||
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME,
|
||||||
|
0, 0, 0, KEY_ALL_ACCESS, 0, &RegKey, 0);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
|
||||||
|
RegResult = RegSetValueExW(RegKey,
|
||||||
|
L"Group", 0, REG_SZ, (PVOID) L"NetworkProvider", sizeof L"NetworkProvider");
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
|
||||||
|
RegResult = RegCreateKeyExW(
|
||||||
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME "\\NetworkProvider",
|
||||||
|
0, 0, 0, KEY_ALL_ACCESS, 0, &RegKey, 0);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
|
||||||
|
RegResult = RegSetValueExW(RegKey,
|
||||||
|
L"Name", 0, REG_SZ, (PVOID) L"" FSP_NP_DESC, sizeof L"" FSP_NP_DESC);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
|
||||||
|
RegResult = RegSetValueExW(RegKey,
|
||||||
|
L"ProviderPath", 0, REG_SZ, (PVOID)ProviderPath, (lstrlenW(ProviderPath) + 1) * sizeof(WCHAR));
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
|
||||||
|
RegResult = RegOpenKeyExW(
|
||||||
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order",
|
||||||
|
0, KEY_ALL_ACCESS, &RegKey);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
|
||||||
|
RegBufferSize = sizeof RegBuffer - sizeof L"," FSP_NP_NAME;
|
||||||
|
RegResult = RegQueryValueExW(RegKey,
|
||||||
|
L"ProviderOrder", 0, &RegType, (PVOID)RegBuffer, &RegBufferSize);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
RegBufferSize /= sizeof(WCHAR);
|
||||||
|
|
||||||
|
FoundProvider = FALSE;
|
||||||
|
RegBuffer[RegBufferSize] = L'\0';
|
||||||
|
P = RegBuffer, Part = P;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (L',' == *P || '\0' == *P)
|
||||||
|
{
|
||||||
|
if (CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
||||||
|
Part, (int)(P - Part),
|
||||||
|
L"" FSP_NP_NAME, (int)(sizeof L"" FSP_NP_NAME - sizeof(WCHAR)) / sizeof(WCHAR)))
|
||||||
|
{
|
||||||
|
FoundProvider = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Part = P + 1;
|
||||||
|
}
|
||||||
|
} while (L'\0' != *P++);
|
||||||
|
|
||||||
|
if (!FoundProvider)
|
||||||
|
{
|
||||||
|
P--;
|
||||||
|
memcpy(P, L"," FSP_NP_NAME, sizeof L"," FSP_NP_NAME);
|
||||||
|
|
||||||
|
RegBufferSize = lstrlenW(RegBuffer);
|
||||||
|
RegBufferSize++;
|
||||||
|
|
||||||
|
RegResult = RegSetValueExW(RegKey,
|
||||||
|
L"ProviderOrder", 0, REG_SZ, (PVOID)RegBuffer, RegBufferSize * sizeof(WCHAR));
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
close_and_exit:
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspNpUnregister(VOID)
|
||||||
|
{
|
||||||
|
WCHAR RegBuffer[1024];
|
||||||
|
PWSTR P, Part;
|
||||||
|
DWORD RegResult, RegType, RegBufferSize;
|
||||||
|
HKEY RegKey;
|
||||||
|
BOOLEAN FoundProvider;
|
||||||
|
|
||||||
|
RegResult = RegOpenKeyExW(
|
||||||
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order",
|
||||||
|
0, KEY_ALL_ACCESS, &RegKey);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
|
||||||
|
RegBufferSize = sizeof RegBuffer - sizeof L"," FSP_NP_NAME;
|
||||||
|
RegResult = RegQueryValueExW(RegKey,
|
||||||
|
L"ProviderOrder", 0, &RegType, (PVOID)RegBuffer, &RegBufferSize);
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
RegBufferSize /= sizeof(WCHAR);
|
||||||
|
|
||||||
|
FoundProvider = FALSE;
|
||||||
|
RegBuffer[RegBufferSize] = L'\0';
|
||||||
|
P = RegBuffer, Part = P;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (L',' == *P || '\0' == *P)
|
||||||
|
{
|
||||||
|
if (CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
||||||
|
Part, (int)(P - Part),
|
||||||
|
L"" FSP_NP_NAME, (int)(sizeof L"" FSP_NP_NAME - sizeof(WCHAR)) / sizeof(WCHAR)))
|
||||||
|
{
|
||||||
|
FoundProvider = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Part = P + 1;
|
||||||
|
}
|
||||||
|
} while (L'\0' != *P++);
|
||||||
|
|
||||||
|
if (FoundProvider)
|
||||||
|
{
|
||||||
|
if (L',' == *P)
|
||||||
|
P++;
|
||||||
|
|
||||||
|
RtlMoveMemory(Part, P, (lstrlenW(P) + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
|
RegBufferSize = lstrlenW(RegBuffer);
|
||||||
|
while (0 < RegBufferSize && ',' == RegBuffer[RegBufferSize - 1])
|
||||||
|
RegBufferSize--;
|
||||||
|
RegBuffer[RegBufferSize] = L'\0';
|
||||||
|
RegBufferSize++;
|
||||||
|
|
||||||
|
RegResult = RegSetValueExW(RegKey,
|
||||||
|
L"ProviderOrder", 0, REG_SZ, (PVOID)RegBuffer, RegBufferSize * sizeof(WCHAR));
|
||||||
|
if (ERROR_SUCCESS != RegResult)
|
||||||
|
goto close_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
|
||||||
|
RegResult = RegDeleteTreeW(
|
||||||
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME);
|
||||||
|
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
close_and_exit:
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
}
|
@ -853,6 +853,8 @@ NTSTATUS FspVolumeRedirQueryPathEx(
|
|||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspVolumeGetNameList(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeTransact(
|
NTSTATUS FspVolumeTransact(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeStop(
|
NTSTATUS FspVolumeStop(
|
||||||
|
@ -35,6 +35,9 @@ static NTSTATUS FspFsctlFileSystemControl(
|
|||||||
if (0 != IrpSp->FileObject->FsContext2)
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
Result = FspVolumeGetName(DeviceObject, Irp, IrpSp);
|
Result = FspVolumeGetName(DeviceObject, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
case FSP_FSCTL_VOLUME_LIST:
|
||||||
|
Result = FspVolumeGetNameList(DeviceObject, Irp, IrpSp);
|
||||||
|
break;
|
||||||
case FSP_FSCTL_TRANSACT:
|
case FSP_FSCTL_TRANSACT:
|
||||||
case FSP_FSCTL_TRANSACT_BATCH:
|
case FSP_FSCTL_TRANSACT_BATCH:
|
||||||
if (0 != IrpSp->FileObject->FsContext2)
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
|
@ -24,6 +24,10 @@ NTSTATUS FspVolumeRedirQueryPathEx(
|
|||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspVolumeGetNameList(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
static NTSTATUS FspVolumeGetNameListNoLock(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeTransact(
|
NTSTATUS FspVolumeTransact(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeStop(
|
NTSTATUS FspVolumeStop(
|
||||||
@ -42,6 +46,8 @@ NTSTATUS FspVolumeWork(
|
|||||||
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
||||||
#pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx)
|
#pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetName)
|
#pragma alloc_text(PAGE, FspVolumeGetName)
|
||||||
|
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
||||||
|
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
||||||
#pragma alloc_text(PAGE, FspVolumeTransact)
|
#pragma alloc_text(PAGE, FspVolumeTransact)
|
||||||
#pragma alloc_text(PAGE, FspVolumeStop)
|
#pragma alloc_text(PAGE, FspVolumeStop)
|
||||||
#pragma alloc_text(PAGE, FspVolumeWork)
|
#pragma alloc_text(PAGE, FspVolumeWork)
|
||||||
@ -60,6 +66,8 @@ typedef struct
|
|||||||
NTSTATUS FspVolumeCreate(
|
NTSTATUS FspVolumeCreate(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FspDeviceGlobalLock();
|
FspDeviceGlobalLock();
|
||||||
Result = FspVolumeCreateNoLock(FsctlDeviceObject, Irp, IrpSp);
|
Result = FspVolumeCreateNoLock(FsctlDeviceObject, Irp, IrpSp);
|
||||||
@ -259,6 +267,8 @@ static VOID FspVolumeCreateRegisterMup(PVOID Context)
|
|||||||
VOID FspVolumeDelete(
|
VOID FspVolumeDelete(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
// !PAGED_CODE();
|
||||||
|
|
||||||
FspDeviceGlobalLock();
|
FspDeviceGlobalLock();
|
||||||
FspVolumeDeleteNoLock(FsctlDeviceObject, Irp, IrpSp);
|
FspVolumeDeleteNoLock(FsctlDeviceObject, Irp, IrpSp);
|
||||||
FspDeviceGlobalUnlock();
|
FspDeviceGlobalUnlock();
|
||||||
@ -381,6 +391,8 @@ static VOID FspVolumeDeleteDelayed(PVOID Context)
|
|||||||
NTSTATUS FspVolumeMount(
|
NTSTATUS FspVolumeMount(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
// !PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FspDeviceGlobalLock();
|
FspDeviceGlobalLock();
|
||||||
Result = FspVolumeMountNoLock(FsctlDeviceObject, Irp, IrpSp);
|
Result = FspVolumeMountNoLock(FsctlDeviceObject, Irp, IrpSp);
|
||||||
@ -532,6 +544,85 @@ NTSTATUS FspVolumeGetName(
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspVolumeGetNameList(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
FspDeviceGlobalLock();
|
||||||
|
Result = FspVolumeGetNameListNoLock(FsctlDeviceObject, Irp, IrpSp);
|
||||||
|
FspDeviceGlobalUnlock();
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspVolumeGetNameListNoLock(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
|
||||||
|
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
|
||||||
|
ASSERT(FSP_FSCTL_VOLUME_LIST == IrpSp->Parameters.FileSystemControl.FsControlCode);
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
||||||
|
PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
PDEVICE_OBJECT *DeviceObjects = 0;
|
||||||
|
ULONG DeviceObjectCount = 0;
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
||||||
|
UNICODE_STRING VolumeList;
|
||||||
|
USHORT Length;
|
||||||
|
|
||||||
|
if (65535/*USHRT_MAX*/ < OutputBufferLength)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
RtlInitEmptyUnicodeString(&VolumeList, SystemBuffer, (USHORT)OutputBufferLength);
|
||||||
|
for (ULONG i = 0; NT_SUCCESS(Result) && DeviceObjectCount > i; i++)
|
||||||
|
if (FspDeviceReference(DeviceObjects[i]))
|
||||||
|
{
|
||||||
|
if (FspFsvolDeviceExtensionKind == FspDeviceExtension(DeviceObjects[i])->Kind)
|
||||||
|
{
|
||||||
|
FsvolDeviceObject = DeviceObjects[i];
|
||||||
|
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
if (FsvolDeviceExtension->FsctlDeviceObject == FsctlDeviceObject &&
|
||||||
|
!FspIoqStopped(FsvolDeviceExtension->Ioq))
|
||||||
|
{
|
||||||
|
Length =
|
||||||
|
FsvolDeviceExtension->VolumeName.Length +
|
||||||
|
FsvolDeviceExtension->VolumePrefix.Length +
|
||||||
|
sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (VolumeList.Length + Length <= VolumeList.MaximumLength)
|
||||||
|
{
|
||||||
|
RtlAppendUnicodeStringToString(&VolumeList, &FsvolDeviceExtension->VolumeName);
|
||||||
|
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
||||||
|
RtlAppendUnicodeStringToString(&VolumeList, &FsvolDeviceExtension->VolumePrefix);
|
||||||
|
VolumeList.Buffer[VolumeList.Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
VolumeList.Length += sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VolumeList.Length = 0;
|
||||||
|
Result = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FspDeviceDereference(DeviceObjects[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FspDeviceDeleteList(DeviceObjects, DeviceObjectCount);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = VolumeList.Length;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FspVolumeTransact(
|
NTSTATUS FspVolumeTransact(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user