driver: generalized volume query into buf, len
Signed-off-by: Casey Bodley <cbodley@umich.edu>
This commit is contained in:
parent
59b4f5410c
commit
b9e8c7f8b2
1 changed files with 52 additions and 120 deletions
|
|
@ -198,9 +198,9 @@ typedef struct _updowncall_entry {
|
||||||
} SetEa;
|
} SetEa;
|
||||||
struct {
|
struct {
|
||||||
HANDLE session;
|
HANDLE session;
|
||||||
ULONGLONG total;
|
FS_INFORMATION_CLASS query;
|
||||||
ULONGLONG user;
|
PVOID buf;
|
||||||
ULONGLONG avail;
|
LONG buf_len;
|
||||||
} Volume;
|
} Volume;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
|
|
@ -978,13 +978,15 @@ NTSTATUS marshal_nfs41_volume(nfs41_updowncall_entry *entry,
|
||||||
goto out;
|
goto out;
|
||||||
else
|
else
|
||||||
tmp += *len;
|
tmp += *len;
|
||||||
header_len = *len + sizeof(HANDLE);
|
header_len = *len + sizeof(HANDLE) + sizeof(FS_INFORMATION_CLASS);
|
||||||
if (header_len > buf_len) {
|
if (header_len > buf_len) {
|
||||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory(tmp, &entry->u.Volume.session, sizeof(HANDLE));
|
RtlCopyMemory(tmp, &entry->u.Volume.session, sizeof(HANDLE));
|
||||||
|
tmp += sizeof(HANDLE);
|
||||||
|
RtlCopyMemory(tmp, &entry->u.Volume.query, sizeof(FS_INFORMATION_CLASS));
|
||||||
*len = header_len;
|
*len = header_len;
|
||||||
|
|
||||||
DbgP("session=0x%x\n", entry->u.Volume.session);
|
DbgP("session=0x%x\n", entry->u.Volume.session);
|
||||||
|
|
@ -1336,13 +1338,15 @@ nfs41_downcall (
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NFS41_VOLUME_QUERY:
|
case NFS41_VOLUME_QUERY:
|
||||||
RtlCopyMemory(&cur->u.Volume.total, buf, sizeof(ULONGLONG));
|
RtlCopyMemory(&tmp->u.Volume.buf_len, buf, sizeof(LONG));
|
||||||
buf += sizeof(ULONGLONG);
|
buf += sizeof(LONG);
|
||||||
RtlCopyMemory(&cur->u.Volume.user, buf, sizeof(ULONGLONG));
|
if (tmp->u.Volume.buf_len > cur->u.Volume.buf_len) {
|
||||||
buf += sizeof(ULONGLONG);
|
cur->status = STATUS_BUFFER_TOO_SMALL;
|
||||||
RtlCopyMemory(&cur->u.Volume.avail, buf, sizeof(ULONGLONG));
|
cur->u.Volume.buf_len = tmp->u.Volume.buf_len;
|
||||||
DbgP("[volume] total %llu user %llu avail %llu\n",
|
break;
|
||||||
cur->u.Volume.total, cur->u.Volume.user, cur->u.Volume.avail);
|
}
|
||||||
|
cur->u.Volume.buf_len = tmp->u.Volume.buf_len;
|
||||||
|
RtlCopyMemory(cur->u.Volume.buf, buf, tmp->u.Volume.buf_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2999,43 +3003,6 @@ static NTSTATUS map_volume_errors(DWORD status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS get_volume_size_info(
|
|
||||||
IN PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext,
|
|
||||||
IN ULONG BytesPerUnit,
|
|
||||||
OUT OPTIONAL PLONGLONG pTotal,
|
|
||||||
OUT OPTIONAL PLONGLONG pUser,
|
|
||||||
OUT OPTIONAL PLONGLONG pAvail)
|
|
||||||
{
|
|
||||||
nfs41_updowncall_entry *entry;
|
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
DbgEn();
|
|
||||||
|
|
||||||
status = nfs41_UpcallCreate(NFS41_VOLUME_QUERY, &entry);
|
|
||||||
if (status)
|
|
||||||
goto out;
|
|
||||||
entry->u.Volume.session = pVNetRootContext->session;
|
|
||||||
|
|
||||||
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
|
|
||||||
status = STATUS_INTERNAL_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->status == NO_ERROR) {
|
|
||||||
if (pTotal) *pTotal = entry->u.Volume.total / BytesPerUnit;
|
|
||||||
if (pUser) *pUser = entry->u.Volume.user / BytesPerUnit;
|
|
||||||
if (pAvail) *pAvail = entry->u.Volume.avail / BytesPerUnit;
|
|
||||||
status = STATUS_SUCCESS;
|
|
||||||
} else {
|
|
||||||
/* map windows ERRORs to NTSTATUS */
|
|
||||||
status = map_volume_errors(entry->status);
|
|
||||||
}
|
|
||||||
RxFreePool(entry);
|
|
||||||
out:
|
|
||||||
DbgEx();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS nfs41_QueryVolumeInformation (
|
NTSTATUS nfs41_QueryVolumeInformation (
|
||||||
IN OUT PRX_CONTEXT RxContext)
|
IN OUT PRX_CONTEXT RxContext)
|
||||||
{
|
{
|
||||||
|
|
@ -3046,6 +3013,7 @@ NTSTATUS nfs41_QueryVolumeInformation (
|
||||||
__notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
|
__notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
|
||||||
PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
|
PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
|
||||||
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
|
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
|
||||||
|
nfs41_updowncall_entry *entry;
|
||||||
|
|
||||||
DbgEn();
|
DbgEn();
|
||||||
print_queryvolume_args(RxContext);
|
print_queryvolume_args(RxContext);
|
||||||
|
|
@ -3065,7 +3033,7 @@ NTSTATUS nfs41_QueryVolumeInformation (
|
||||||
/* Have to have status success for Notepad to be happy */
|
/* Have to have status success for Notepad to be happy */
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
RtlZeroMemory(pVolInfo, sizeof(FILE_FS_VOLUME_INFORMATION));
|
RtlZeroMemory(pVolInfo, sizeof(FILE_FS_VOLUME_INFORMATION));
|
||||||
pVolInfo->VolumeCreationTime.QuadPart = 0;
|
pVolInfo->VolumeCreationTime.QuadPart = 0;
|
||||||
|
|
@ -3074,8 +3042,9 @@ NTSTATUS nfs41_QueryVolumeInformation (
|
||||||
RtlCopyMemory(&pVolInfo->VolumeLabel[0], (PVOID)Label.Buffer, Label.Length);
|
RtlCopyMemory(&pVolInfo->VolumeLabel[0], (PVOID)Label.Buffer, Label.Length);
|
||||||
RxContext->Info.LengthRemaining -= SizeUsed;
|
RxContext->Info.LengthRemaining -= SizeUsed;
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case FileFsDeviceInformation:
|
case FileFsDeviceInformation:
|
||||||
{
|
{
|
||||||
PFILE_FS_DEVICE_INFORMATION pDevInfo = RxContext->Info.Buffer;
|
PFILE_FS_DEVICE_INFORMATION pDevInfo = RxContext->Info.Buffer;
|
||||||
|
|
@ -3084,88 +3053,51 @@ NTSTATUS nfs41_QueryVolumeInformation (
|
||||||
if (RemainingLength < SizeUsed) {
|
if (RemainingLength < SizeUsed) {
|
||||||
status = STATUS_BUFFER_TOO_SMALL;
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
RxContext->InformationToReturn = SizeUsed;
|
RxContext->InformationToReturn = SizeUsed;
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
RtlZeroMemory(pDevInfo, SizeUsed);
|
RtlZeroMemory(pDevInfo, SizeUsed);
|
||||||
pDevInfo->DeviceType = RxContext->pFcb->pNetRoot->DeviceType;
|
pDevInfo->DeviceType = RxContext->pFcb->pNetRoot->DeviceType;
|
||||||
pDevInfo->Characteristics = FILE_REMOTE_DEVICE; // | FILE_READ_ONLY_DEVICE;
|
pDevInfo->Characteristics = FILE_REMOTE_DEVICE; // | FILE_READ_ONLY_DEVICE;
|
||||||
RxContext->Info.LengthRemaining -= SizeUsed;
|
RxContext->Info.LengthRemaining -= SizeUsed;
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case FileFsAttributeInformation:
|
|
||||||
{
|
|
||||||
PFILE_FS_ATTRIBUTE_INFORMATION pAttrInfo = RxContext->Info.Buffer;
|
|
||||||
//DECLARE_CONST_UNICODE_STRING(FSName, L"PNFS Stub FileSystemName");
|
|
||||||
DECLARE_CONST_UNICODE_STRING(FSName, L"NFS");
|
|
||||||
|
|
||||||
SizeUsed = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + FSName.Length;
|
|
||||||
if (RemainingLength < SizeUsed) {
|
|
||||||
status = STATUS_BUFFER_TOO_SMALL;
|
|
||||||
RxContext->InformationToReturn -= SizeUsed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
RtlZeroMemory(pAttrInfo, SizeUsed);
|
|
||||||
pAttrInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES |
|
|
||||||
FILE_CASE_SENSITIVE_SEARCH |
|
|
||||||
FILE_SUPPORTS_REMOTE_STORAGE;
|
|
||||||
pAttrInfo->MaximumComponentNameLength = 64;
|
|
||||||
pAttrInfo->FileSystemNameLength = FSName.Length;
|
|
||||||
RtlCopyMemory(pAttrInfo->FileSystemName, FSName.Buffer, FSName.Length);
|
|
||||||
RxContext->Info.LengthRemaining -= SizeUsed;
|
|
||||||
status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FileFsFullSizeInformation:
|
|
||||||
{
|
|
||||||
PFILE_FS_FULL_SIZE_INFORMATION pSizeInfo =
|
|
||||||
(PFILE_FS_FULL_SIZE_INFORMATION) RxContext->Info.Buffer;
|
|
||||||
|
|
||||||
SizeUsed = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
|
|
||||||
if (RemainingLength < SizeUsed) {
|
|
||||||
status = STATUS_BUFFER_TOO_SMALL;
|
|
||||||
RxContext->InformationToReturn = SizeUsed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
RtlZeroMemory(pSizeInfo, SizeUsed);
|
|
||||||
pSizeInfo->SectorsPerAllocationUnit = 8;
|
|
||||||
pSizeInfo->BytesPerSector = 512;
|
|
||||||
|
|
||||||
status = get_volume_size_info(pVNetRootContext,
|
|
||||||
pSizeInfo->SectorsPerAllocationUnit * pSizeInfo->BytesPerSector,
|
|
||||||
&pSizeInfo->TotalAllocationUnits.QuadPart,
|
|
||||||
&pSizeInfo->CallerAvailableAllocationUnits.QuadPart,
|
|
||||||
&pSizeInfo->ActualAvailableAllocationUnits.QuadPart);
|
|
||||||
RxContext->Info.LengthRemaining -= SizeUsed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FileFsSizeInformation:
|
case FileFsSizeInformation:
|
||||||
{
|
case FileFsAttributeInformation:
|
||||||
PFILE_FS_SIZE_INFORMATION pSizeInfo =
|
case FileFsFullSizeInformation:
|
||||||
(PFILE_FS_SIZE_INFORMATION) RxContext->Info.Buffer;
|
|
||||||
|
|
||||||
SizeUsed = sizeof(FILE_FS_SIZE_INFORMATION);
|
|
||||||
if (RemainingLength < SizeUsed) {
|
|
||||||
status = STATUS_BUFFER_TOO_SMALL;
|
|
||||||
RxContext->InformationToReturn = SizeUsed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
RtlZeroMemory(pSizeInfo, SizeUsed);
|
|
||||||
pSizeInfo->SectorsPerAllocationUnit = 8;
|
|
||||||
pSizeInfo->BytesPerSector = 512;
|
|
||||||
|
|
||||||
status = get_volume_size_info(pVNetRootContext,
|
|
||||||
pSizeInfo->SectorsPerAllocationUnit * pSizeInfo->BytesPerSector,
|
|
||||||
&pSizeInfo->TotalAllocationUnits.QuadPart,
|
|
||||||
&pSizeInfo->AvailableAllocationUnits.QuadPart,
|
|
||||||
NULL);
|
|
||||||
RxContext->Info.LengthRemaining -= SizeUsed;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
break;
|
default:
|
||||||
|
DbgP("unhandled fs query class %d\n", InfoClass);
|
||||||
|
status = STATUS_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = nfs41_UpcallCreate(NFS41_VOLUME_QUERY, &entry);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
entry->u.Volume.session = pVNetRootContext->session;
|
||||||
|
entry->u.Volume.query = InfoClass;
|
||||||
|
entry->u.Volume.buf = RxContext->Info.Buffer;
|
||||||
|
entry->u.Volume.buf_len = RxContext->Info.LengthRemaining;
|
||||||
|
|
||||||
|
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
|
||||||
|
status = STATUS_INTERNAL_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->status == STATUS_BUFFER_TOO_SMALL) {
|
||||||
|
RxContext->InformationToReturn = entry->u.Volume.buf_len;
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
} else if (entry->status == STATUS_SUCCESS) {
|
||||||
|
RxContext->Info.LengthRemaining -= entry->u.Volume.buf_len;
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
status = map_volume_errors(entry->status);
|
||||||
|
}
|
||||||
|
RxFreePool(entry);
|
||||||
|
out:
|
||||||
DbgEx();
|
DbgEx();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue