📄 init.c
字号:
NTSTATUS
SmbCeGetOperatingSystemInformation(
VOID
)
{
ULONG Storage[256];
UNICODE_STRING UnicodeString;
HANDLE hRegistryKey;
NTSTATUS Status;
ULONG BytesRead;
OBJECT_ATTRIBUTES ObjectAttributes;
PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
KEY_VALUE_PARTIAL_INFORMATION InitialPartialInformationValue;
ULONG AllocationLength;
PAGED_CODE();
ASSERT(SmbCeContext.OperatingSystem.Buffer == NULL);
ASSERT(SmbCeContext.LanmanType.Buffer == NULL);
RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_CURRENT_WINDOWS_VERSION);
InitializeObjectAttributes(
&ObjectAttributes,
&UnicodeString, // name
OBJ_CASE_INSENSITIVE, // attributes
NULL, // root
NULL); // security descriptor
Status = ZwOpenKey (&hRegistryKey, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status)) {
return Status;
}
RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_OPERATING_SYSTEM);
Status = ZwQueryValueKey(
hRegistryKey,
&UnicodeString,
KeyValueFullInformation,
Value,
sizeof(Storage),
&BytesRead);
if (NT_SUCCESS(Status)) {
SmbCeContext.OperatingSystem.MaximumLength =
(USHORT)Value->DataLength + sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME) - sizeof(WCHAR);
SmbCeContext.OperatingSystem.Length = SmbCeContext.OperatingSystem.MaximumLength - sizeof(WCHAR);
SmbCeContext.OperatingSystem.Buffer = RxAllocatePoolWithTag(
PagedPool,
SmbCeContext.OperatingSystem.MaximumLength,
MRXSMB_MISC_POOLTAG);
if (SmbCeContext.OperatingSystem.Buffer != NULL) {
RtlCopyMemory(SmbCeContext.OperatingSystem.Buffer,
SMBMRX_CONFIG_OPERATING_SYSTEM_NAME,
sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME));
RtlCopyMemory((SmbCeContext.OperatingSystem.Buffer +
(sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME)/sizeof(WCHAR)) - 1),
(PCHAR)Value+Value->DataOffset,
Value->DataLength);
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
if (NT_SUCCESS(Status)) {
RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_OPERATING_SYSTEM_VERSION);
Status = ZwQueryValueKey(
hRegistryKey,
&UnicodeString,
KeyValueFullInformation,
Value,
sizeof(Storage),
&BytesRead);
if (NT_SUCCESS(Status)) {
SmbCeContext.LanmanType.MaximumLength =
SmbCeContext.LanmanType.Length = (USHORT)Value->DataLength +
sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME) -
sizeof(WCHAR);
SmbCeContext.LanmanType.Buffer = RxAllocatePoolWithTag(
PagedPool,
SmbCeContext.LanmanType.Length,
MRXSMB_MISC_POOLTAG);
if (SmbCeContext.LanmanType.Buffer != NULL) {
RtlCopyMemory(
SmbCeContext.LanmanType.Buffer,
SMBMRX_CONFIG_OPERATING_SYSTEM_NAME,
sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME));
RtlCopyMemory(
(SmbCeContext.LanmanType.Buffer +
(sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME)/sizeof(WCHAR)) - 1),
(PCHAR)Value+Value->DataOffset,
Value->DataLength);
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
}
ZwClose(hRegistryKey);
return Status;
}
NTSTATUS
MRxSmbPnpIrpCompletion(
PDEVICE_OBJECT pDeviceObject,
PIRP pIrp,
PVOID pContext)
/*++
Routine Description:
This routine completes the PNP irp for SMB mini redirector.
Arguments:
DeviceObject - Supplies the device object for the packet being processed.
pIrp - Supplies the Irp being processed
pContext - the completion context
--*/
{
PKEVENT pCompletionEvent = pContext;
KeSetEvent(
pCompletionEvent,
IO_NO_INCREMENT,
FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
MRxSmbProcessPnpIrp(
PIRP pIrp)
/*++
Routine Description:
This routine initiates the processing of PNP irps for SMB mini redirector.
Arguments:
pIrp - Supplies the Irp being processed
Notes:
The query target device relation is the only call that is implemented
currently. This is done by returing the PDO associated with the transport
connection object. In any case this routine assumes the responsibility of
completing the IRP and return STATUS_PENDING.
This routine also writes an error log entry when the underlying transport
fails the request. This should help us isolate the responsibility.
--*/
{
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( pIrp );
IoMarkIrpPending(pIrp);
if ((IrpSp->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS) &&
(IrpSp->Parameters.QueryDeviceRelations.Type==TargetDeviceRelation)) {
PIRP pAssociatedIrp;
PFILE_OBJECT pConnectionFileObject = NULL;
PMRX_FCB pFcb = NULL;
PSMBCEDB_SERVER_ENTRY pServerEntry = NULL;
BOOLEAN ServerTransportReferenced = FALSE;
// Locate the transport connection object for the associated file object
// and forward the query to that device.
if ((IrpSp->FileObject != NULL) &&
((pFcb = IrpSp->FileObject->FsContext) != NULL) &&
(NodeTypeIsFcb(pFcb))) {
PMRX_SRV_CALL pSrvCall;
PMRX_NET_ROOT pNetRoot;
if (((pNetRoot = pFcb->pNetRoot) != NULL) &&
((pSrvCall = pNetRoot->pSrvCall) != NULL)) {
pServerEntry = pSrvCall->Context;
if (pServerEntry != NULL) {
SmbCeAcquireResource();
Status = SmbCeReferenceServerTransport(&pServerEntry->pTransport);
if (Status == STATUS_SUCCESS) {
pConnectionFileObject = SmbCepReferenceEndpointFileObject(
pServerEntry->pTransport);
ServerTransportReferenced = TRUE;
}
SmbCeReleaseResource();
}
}
}
if (pConnectionFileObject != NULL) {
PDEVICE_OBJECT pRelatedDeviceObject;
PIO_STACK_LOCATION pIrpStackLocation,
pAssociatedIrpStackLocation;
pRelatedDeviceObject = IoGetRelatedDeviceObject(pConnectionFileObject);
pAssociatedIrp = IoAllocateIrp(
pRelatedDeviceObject->StackSize,
FALSE);
if (pAssociatedIrp != NULL) {
KEVENT CompletionEvent;
KeInitializeEvent( &CompletionEvent,
SynchronizationEvent,
FALSE );
// Fill up the associated IRP and call the underlying driver.
pAssociatedIrpStackLocation = IoGetNextIrpStackLocation(pAssociatedIrp);
pIrpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
*pAssociatedIrpStackLocation = *pIrpStackLocation;
pAssociatedIrpStackLocation->FileObject = pConnectionFileObject;
pAssociatedIrpStackLocation->DeviceObject = pRelatedDeviceObject;
IoSetCompletionRoutine(
pAssociatedIrp,
MRxSmbPnpIrpCompletion,
&CompletionEvent,
TRUE,TRUE,TRUE);
pAssociatedIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Status = IoCallDriver(pRelatedDeviceObject,pAssociatedIrp);
if (Status == STATUS_PENDING) {
(VOID) KeWaitForSingleObject(
&CompletionEvent,
Executive,
KernelMode,
FALSE,
(PLARGE_INTEGER) NULL );
}
pIrp->IoStatus = pAssociatedIrp->IoStatus;
Status = pIrp->IoStatus.Status;
ObDereferenceObject(pConnectionFileObject);
IoFreeIrp(pAssociatedIrp);
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
} else {
Status = STATUS_INVALID_DEVICE_REQUEST;
}
if (ServerTransportReferenced) {
SmbCeDereferenceServerTransport(&pServerEntry->pTransport);
}
} else {
Status = STATUS_INVALID_DEVICE_REQUEST;
}
if (Status != STATUS_PENDING) {
pIrp->IoStatus.Status = Status;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
Status = STATUS_PENDING;
}
return STATUS_PENDING;
}
NTSTATUS
MRxSmbFsdDispatch (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine implements the FSD dispatch for the smbmini DRIVER object.
Arguments:
DeviceObject - Supplies the device object for the packet being processed.
Irp - Supplies the Irp being processed
Return Value:
RXSTATUS - The Fsd status for the Irp
--*/
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); //ok4ioget
UCHAR MajorFunctionCode = IrpSp->MajorFunction;
ULONG MinorFunctionCode = IrpSp->MinorFunction;
BOOLEAN ForwardRequestToWrapper = TRUE;
PSMBCEDB_SERVER_ENTRY pServerEntry = NULL;
NTSTATUS Status;
PAGED_CODE();
ASSERT(DeviceObject==(PDEVICE_OBJECT)MRxSmbDeviceObject);
if (DeviceObject!=(PDEVICE_OBJECT)MRxSmbDeviceObject) {
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return (STATUS_INVALID_DEVICE_REQUEST);
}
Status = STATUS_SUCCESS;
FsRtlEnterFileSystem();
// PnP IRPs are handled outside of the wrapper
if (IrpSp->MajorFunction == IRP_MJ_PNP) {
ForwardRequestToWrapper = FALSE;
Status = MRxSmbProcessPnpIrp(Irp);
}
FsRtlExitFileSystem();
if ((Status == STATUS_SUCCESS) &&
ForwardRequestToWrapper){
Status = RxFsdDispatch((PRDBSS_DEVICE_OBJECT)MRxSmbDeviceObject,Irp);
} else if (Status != STATUS_PENDING) {
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
}
if (pServerEntry != NULL ) {
FsRtlEnterFileSystem();
pServerEntry->TransportSpecifiedByUser = 0;
SmbCeDereferenceServerEntry(pServerEntry);
FsRtlExitFileSystem();
}
return Status;
}
NTSTATUS
MRxSmbDeallocateForFcb (
IN OUT PMRX_FCB pFcb
)
{
PAGED_CODE();
return(STATUS_SUCCESS);
}
NTSTATUS
MRxSmbDeallocateForFobx (
IN OUT PMRX_FOBX pFobx
)
{
PAGED_CODE();
IF_DEBUG {
PMRX_SMB_FOBX smbFobx = MRxSmbGetFileObjectExtension(pFobx);
PMRX_SRV_OPEN SrvOpen = pFobx->pSrvOpen;
PMRX_FCB Fcb = SrvOpen->pFcb;
if (smbFobx && FlagOn(smbFobx->Enumeration.Flags,SMBFOBX_ENUMFLAG_LOUD_FINALIZE)) {
DbgPrint("Finalizobx side buffer %p %p %p %pon %wZ\n",
0, 0, // sidebuffer, count
smbFobx,pFobx,GET_ALREADY_PREFIXED_NAME(SrvOpen,Fcb)
);
}
}
return(STATUS_SUCCESS);
}
NTSTATUS
MRxSmbGetUlongRegistryParameter(
__in HANDLE ParametersHandle,
__in PWSTR ParameterName,
__out PULONG ParamUlong,
__in BOOLEAN LogFailure
)
{
ULONG Storage[16];
PKEY_VALUE_PARTIAL_INFORMATION Value;
ULONG ValueSize;
UNICODE_STRING UnicodeString;
NTSTATUS Status;
ULONG BytesRead;
PAGED_CODE(); //INIT
Value = (PKEY_VALUE_PARTIAL_INFORMATION)Storage;
ValueSize = sizeof(Storage);
RtlInitUnicodeString(&UnicodeString, ParameterName);
Status = ZwQueryValueKey(ParametersHandle,
&UnicodeString,
KeyValuePartialInformation,
Value,
ValueSize,
&BytesRead);
if (NT_SUCCESS(Status)) {
if (Value->Type == REG_DWORD) {
PULONG ConfigValue = (PULONG)&Value->Data[0];
*ParamUlong = *((PULONG)ConfigValue);
return(STATUS_SUCCESS);
} else {
Status = STATUS_INVALID_PARAMETER;
}
}
if (!LogFailure) { return Status; }
RxLogFailureWithBuffer(
MRxSmbDeviceObject,
NULL,
EVENT_RDR_CANT_READ_REGISTRY,
Status,
ParameterName,
(USHORT)(wcslen(ParameterName)*sizeof(WCHAR))
);
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -