📄 ea.c
字号:
ULONG
MRxSmbNtFullEaSizeToOs2 (
IN PFILE_FULL_EA_INFORMATION NtFullEa
)
/*++
Routine Description:
Get the number of bytes that would be required to represent the
NT full EA list in OS/2 1.2 style. This routine assumes that
at least one EA is present in the buffer.
Arguments:
NtFullEa - a pointer to the list of NT EAs.
Return Value:
ULONG - number of bytes required to hold the EAs in OS/2 1.2 format.
--*/
{
ULONG size;
PAGED_CODE();
//
// Walk through the EAs, adding up the total size required to
// hold them in OS/2 format.
//
for ( size = FIELD_OFFSET(FEALIST, list[0]);
NtFullEa->NextEntryOffset != 0;
NtFullEa = (PFILE_FULL_EA_INFORMATION)(
(PCHAR)NtFullEa + NtFullEa->NextEntryOffset ) ) {
size += SmbGetOs2SizeOfNtFullEa( NtFullEa );
}
size += SmbGetOs2SizeOfNtFullEa( NtFullEa );
return size;
}
VOID
MRxSmbNtFullListToOs2 (
IN PFILE_FULL_EA_INFORMATION NtEaList,
IN PFEALIST FeaList
)
/*++
Routine Description:
Converts a single NT FULL EA list to OS/2 FEALIST style. The FEALIST
need not have any particular alignment.
It is the callers responsibility to ensure that FeaList is large enough.
Arguments:
NtEaList - An NT style get EA list to be converted to OS/2 format.
FeaList - Where to place the OS/2 1.2 style FEALIST.
Return Value:
none.
--*/
{
PFEA fea = FeaList->list;
PFILE_FULL_EA_INFORMATION ntFullEa = NtEaList;
PAGED_CODE();
//
// Copy the Eas up until the last one
//
while ( ntFullEa->NextEntryOffset != 0 ) {
//
// Copy the NT format EA to OS/2 1.2 format and set the fea
// pointer for the next iteration.
//
fea = MRxSmbNtFullEaToOs2( fea, ntFullEa );
ntFullEa = (PFILE_FULL_EA_INFORMATION)((PCHAR)ntFullEa + ntFullEa->NextEntryOffset);
}
// Now copy the last entry.
fea = MRxSmbNtFullEaToOs2( fea, ntFullEa );
//
// Set the number of bytes in the FEALIST.
//
SmbPutUlong(
&FeaList->cbList,
(ULONG)((PCHAR)fea - (PCHAR)FeaList)
);
}
PVOID
MRxSmbNtFullEaToOs2 (
OUT PFEA Fea,
IN PFILE_FULL_EA_INFORMATION NtFullEa
)
/*++
Routine Description:
Converts a single NT full EA to OS/2 FEA style. The FEA need not have
any particular alignment. This routine makes no checks on buffer
overrunning--this is the responsibility of the calling routine.
Arguments:
Fea - a pointer to the location where the OS/2 FEA is to be written.
NtFullEa - a pointer to the NT full EA.
Return Value:
A pointer to the location after the last byte written.
--*/
{
PCHAR ptr;
PAGED_CODE();
Fea->fEA = (UCHAR)NtFullEa->Flags;
Fea->cbName = NtFullEa->EaNameLength;
SmbPutUshort( &Fea->cbValue, NtFullEa->EaValueLength );
ptr = (PCHAR)(Fea + 1);
RtlCopyMemory( ptr, NtFullEa->EaName, NtFullEa->EaNameLength );
ptr += NtFullEa->EaNameLength;
*ptr++ = '\0';
RtlCopyMemory(
ptr,
NtFullEa->EaName + NtFullEa->EaNameLength + 1,
NtFullEa->EaValueLength
);
return (ptr + NtFullEa->EaValueLength);
}
NTSTATUS
MRxSmbSetEaList(
IN PRX_CONTEXT RxContext,
IN PFEALIST ServerEaList
)
/*++
Routine Description:
This routine implements the NtQueryEaFile api.
It returns the following information:
Arguments:
IN PFEALIST ServerEaList - Eas to be sent to the server.
Return Value:
Status - Result of the operation.
--*/
{
RxCaptureFobx;
PMRX_SMB_SRV_OPEN smbSrvOpen;
NTSTATUS Status;
USHORT Setup = TRANS2_SET_FILE_INFORMATION;
REQ_SET_FILE_INFORMATION SetFileInfoRequest;
RESP_SET_FILE_INFORMATION SetFileInfoResponse;
PBYTE pInputParamBuffer = NULL;
PBYTE pOutputParamBuffer = NULL;
PBYTE pInputDataBuffer = NULL;
PBYTE pOutputDataBuffer = NULL;
ULONG InputParamBufferLength = 0;
ULONG OutputParamBufferLength = 0;
ULONG InputDataBufferLength = 0;
ULONG OutputDataBufferLength = 0;
PAGED_CODE();
RxDbgTrace(+1, Dbg, ("MRxSmbSetEaList...\n"));
Status = STATUS_MORE_PROCESSING_REQUIRED;
SetFileInfoResponse.EaErrorOffset = 0;
smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);
if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
PSMB_TRANSACTION_OPTIONS pTransactionOptions = &RxDefaultTransactionOptions;
SMB_TRANSACTION_RESUMPTION_CONTEXT ResumptionContext;
SetFileInfoRequest.Fid = smbSrvOpen->Fid;
SetFileInfoRequest.InformationLevel = SMB_INFO_SET_EAS;
SetFileInfoRequest.Flags = 0;
Status = SmbCeTransact(
RxContext, // the RXContext for the transaction
pTransactionOptions, // transaction options
&Setup, // the setup buffer
sizeof(Setup), // setup buffer length
NULL, // the output setup buffer
0, // output setup buffer length
&SetFileInfoRequest, // Input Param Buffer
sizeof(SetFileInfoRequest), // Input param buffer length
&SetFileInfoResponse, // Output param buffer
sizeof(SetFileInfoResponse), // output param buffer length
ServerEaList, // Input data buffer
SmbGetUlong(&ServerEaList->cbList), // Input data buffer length
NULL, // output data buffer
0, // output data buffer length
&ResumptionContext // the resumption context
);
}
if (!NT_SUCCESS(Status)) {
USHORT EaErrorOffset = SetFileInfoResponse.EaErrorOffset;
RxDbgTrace( 0, Dbg, ("MRxSmbSetEaList: Failed .. returning %lx/%lx\n",Status,EaErrorOffset));
RxContext->InformationToReturn = (EaErrorOffset);
}
RxDbgTrace(-1, Dbg, ("MRxSmbSetEaList...exit\n"));
return Status;
}
NTSTATUS
MRxSmbQueryQuotaInformation(
IN OUT PRX_CONTEXT RxContext)
{
RxCaptureFobx;
PMRX_SMB_SRV_OPEN smbSrvOpen;
NTSTATUS Status;
USHORT Setup = NT_TRANSACT_QUERY_QUOTA;
PSID StartSid;
ULONG StartSidLength;
REQ_NT_QUERY_FS_QUOTA_INFO QueryQuotaInfoRequest;
RESP_NT_QUERY_FS_QUOTA_INFO QueryQuotaInfoResponse;
PBYTE pInputParamBuffer = NULL;
PBYTE pOutputParamBuffer = NULL;
PBYTE pInputDataBuffer = NULL;
PBYTE pOutputDataBuffer = NULL;
ULONG InputParamBufferLength = 0;
ULONG OutputParamBufferLength = 0;
ULONG InputDataBufferLength = 0;
ULONG OutputDataBufferLength = 0;
PAGED_CODE();
RxDbgTrace(+1, Dbg, ("MRxSmbQueryQuotaInformation...\n"));
Status = STATUS_MORE_PROCESSING_REQUIRED;
if (capFobx != NULL) {
smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);
}
if ((capFobx == NULL) ||
(smbSrvOpen == NULL)) {
Status = STATUS_INVALID_PARAMETER;
}
if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
StartSid = RxContext->QueryQuota.StartSid;
if (StartSid != NULL) {
StartSidLength = RtlLengthRequiredSid(((PISID)StartSid)->SubAuthorityCount);
} else {
StartSidLength = 0;
}
QueryQuotaInfoRequest.Fid = smbSrvOpen->Fid;
QueryQuotaInfoRequest.ReturnSingleEntry = RxContext->QueryQuota.ReturnSingleEntry;
QueryQuotaInfoRequest.RestartScan = RxContext->QueryQuota.RestartScan;
QueryQuotaInfoRequest.SidListLength = RxContext->QueryQuota.SidListLength;
QueryQuotaInfoRequest.StartSidOffset = ROUND_UP_COUNT(
RxContext->QueryQuota.SidListLength,
sizeof(ULONG));
QueryQuotaInfoRequest.StartSidLength = StartSidLength;
// The input data buffer to be supplied to the server consists of two pieces
// of information the start sid and the sid list. Currently the I/O
// subsystem allocates them in contigous memory. In such cases we avoid
// another allocation by reusing the same buffer. If this condition is
// not satisfied we allocate a buffer large enough for both the
// components and copy them over.
__assume_bound( RxContext->QueryQuota.SidListLength );
__assume_bound( StartSidLength );
InputDataBufferLength = ROUND_UP_COUNT(
RxContext->QueryQuota.SidListLength,
sizeof(ULONG)) +
StartSidLength;
QueryQuotaInfoRequest.StartSidLength = StartSidLength;
if (((PBYTE)RxContext->QueryQuota.SidList +
ROUND_UP_COUNT(RxContext->QueryQuota.SidListLength,sizeof(ULONG))) !=
RxContext->QueryQuota.StartSid) {
pInputDataBuffer = RxAllocatePoolWithTag(
PagedPool,
InputDataBufferLength,
MRXSMB_MISC_POOLTAG);
if (pInputDataBuffer != NULL) {
RtlCopyMemory(
pInputDataBuffer ,
RxContext->QueryQuota.SidList,
RxContext->QueryQuota.SidListLength);
RtlCopyMemory(
pInputDataBuffer + QueryQuotaInfoRequest.StartSidOffset,
StartSid,
StartSidLength);
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
} else {
pInputDataBuffer = (PBYTE)RxContext->QueryQuota.SidList;
}
if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
SMB_TRANSACTION_OPTIONS TransactionOptions = RxDefaultTransactionOptions;
SMB_TRANSACTION_RESUMPTION_CONTEXT ResumptionContext;
TransactionOptions.NtTransactFunction = NT_TRANSACT_QUERY_QUOTA;
pOutputDataBuffer = RxContext->Info.Buffer;
OutputDataBufferLength = RxContext->Info.LengthRemaining;
Status = SmbCeTransact(
RxContext, // the RXContext for the transaction
&TransactionOptions, // transaction options
&Setup, // the setup buffer
sizeof(Setup), // setup buffer length
NULL, // the output setup buffer
0, // output setup buffer length
&QueryQuotaInfoRequest, // Input Param Buffer
sizeof(QueryQuotaInfoRequest), // Input param buffer length
&QueryQuotaInfoResponse, // Output param buffer
sizeof(QueryQuotaInfoResponse), // output param buffer length
pInputDataBuffer, // Input data buffer
InputDataBufferLength, // Input data buffer length
pOutputDataBuffer, // output data buffer
OutputDataBufferLength, // output data buffer length
&ResumptionContext // the resumption context
);
}
if ((pInputDataBuffer != NULL) &&
(pInputDataBuffer != (PBYTE)RxContext->QueryQuota.SidList)) {
RxFreePool(pInputDataBuffer);
}
}
if (!NT_SUCCESS(Status)) {
RxContext->InformationToReturn = 0;
} else {
RxContext->InformationToReturn = QueryQuotaInfoResponse.Length;
}
RxDbgTrace(-1, Dbg, ("MRxSmbQueryQuotaInformation...exit\n"));
return Status;
}
NTSTATUS
MRxSmbSetQuotaInformation(
IN OUT PRX_CONTEXT RxContext)
{
RxCaptureFobx;
PMRX_SMB_SRV_OPEN smbSrvOpen;
NTSTATUS Status;
USHORT Setup = NT_TRANSACT_SET_QUOTA;
REQ_NT_SET_FS_QUOTA_INFO SetQuotaInfoRequest;
PBYTE pInputParamBuffer = NULL;
PBYTE pOutputParamBuffer = NULL;
PBYTE pInputDataBuffer = NULL;
PBYTE pOutputDataBuffer = NULL;
ULONG InputParamBufferLength = 0;
ULONG OutputParamBufferLength = 0;
ULONG InputDataBufferLength = 0;
ULONG OutputDataBufferLength = 0;
PAGED_CODE();
RxDbgTrace(+1, Dbg, ("MRxSmbSetQuotaInformation...\n"));
Status = STATUS_MORE_PROCESSING_REQUIRED;
if (capFobx != NULL) {
smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);
}
if ((capFobx == NULL) ||
(smbSrvOpen == NULL)) {
Status = STATUS_INVALID_PARAMETER;
}
if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
SMB_TRANSACTION_OPTIONS TransactionOptions = RxDefaultTransactionOptions;
SMB_TRANSACTION_RESUMPTION_CONTEXT ResumptionContext;
TransactionOptions.NtTransactFunction = NT_TRANSACT_SET_QUOTA;
SetQuotaInfoRequest.Fid = smbSrvOpen->Fid;
pInputDataBuffer = RxContext->Info.Buffer;
InputDataBufferLength = RxContext->Info.LengthRemaining;
Status = SmbCeTransact(
RxContext, // the RXContext for the transaction
&TransactionOptions, // transaction options
&Setup, // the setup buffer
sizeof(Setup), // setup buffer length
NULL, // the output setup buffer
0, // output setup buffer length
&SetQuotaInfoRequest, // Input Param Buffer
sizeof(SetQuotaInfoRequest), // Input param buffer length
pOutputParamBuffer, // Output param buffer
OutputParamBufferLength, // output param buffer length
pInputDataBuffer, // Input data buffer
InputDataBufferLength, // Input data buffer length
pOutputDataBuffer, // output data buffer
OutputDataBufferLength, // output data buffer length
&ResumptionContext // the resumption context
);
}
RxDbgTrace(-1, Dbg, ("MRxSmbSetQuotaInformation...exit\n"));
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -