Example #1
0
NTSTATUS
CmpDoFileSetSize(
    PHHIVE      Hive,
    ULONG       FileType,
    ULONG       FileSize,
    ULONG       OldFileSize
    )
/*++

Routine Description:

    This routine sets the size of a file.  It must not return until
    the size is guaranteed.

    It is environment specific.

    Must be running in the context of the cmp worker thread.

Arguments:

    Hive - Hive we are doing I/O for

    FileType - which supporting file to use

    FileSize - 32 bit value to set the file's size to

    OldFileSize - old file size, in order to determine if this is a shrink;
                - ignored if file type is not primary, or hive doesn't use 
                the mapped views technique

Return Value:

    FALSE if failure
    TRUE if success

--*/
{
    PCMHIVE                         CmHive;
    HANDLE                          FileHandle;
    NTSTATUS                        Status;
    FILE_END_OF_FILE_INFORMATION    FileInfo;
    IO_STATUS_BLOCK                 IoStatus;
    BOOLEAN                         oldFlag;
    LARGE_INTEGER                   FileOffset;         // where the mapping starts

    ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0);

    CmHive = (PCMHIVE)Hive;
    FileHandle = CmHive->FileHandles[FileType];
    if (FileHandle == NULL) {
        return TRUE;
    }

    //
    // disable hard error popups, to avoid self deadlock on bogus devices
    //
    oldFlag = IoSetThreadHardErrorMode(FALSE);

    FileInfo.EndOfFile.HighPart = 0L;
    if( FileType == HFILE_TYPE_PRIMARY ) {
        FileInfo.EndOfFile.LowPart  = ROUND_UP(FileSize, CM_FILE_GROW_INCREMENT);
    } else {
        FileInfo.EndOfFile.LowPart  = FileSize;
    }

    ASSERT_PASSIVE_LEVEL();

    Status = ZwSetInformationFile(
                FileHandle,
                &IoStatus,
                (PVOID)&FileInfo,
                sizeof(FILE_END_OF_FILE_INFORMATION),
                FileEndOfFileInformation
                );

    if (NT_SUCCESS(Status)) {
        ASSERT(IoStatus.Status == Status);
    } else {
        
        //
        // set debugging info
        //
        CmRegistryIODebug.Action = CmpIoFileSetSize;
        CmRegistryIODebug.Handle = FileHandle;
        CmRegistryIODebug.Status = Status;
#if DBG
        DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"CmpFileSetSize:\tHandle=%08lx  OldLength = %08lx NewLength=%08lx  \n", 
                                                        FileHandle, OldFileSize, FileSize);
#endif
        if( (Status == STATUS_DISK_FULL) && ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock) ) {
            DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"Disk is full while attempting to grow file %lx; will flush upon lock release\n",FileHandle);
            CmpFlushOnLockRelease = TRUE;;
        }
    }

    //
    // restore hard error popups mode
    //
    IoSetThreadHardErrorMode(oldFlag);
    

    //
    // purge
    //
    if( HiveWritesThroughCache(Hive,FileType) && (OldFileSize > FileSize)) {
        //
        // first we have to unmap any possible mapped views in the last 256K window
        // to avoid deadlock on CcWaitOnActiveCount inside CcPurgeCacheSection call below
        //
        ULONG   Offset = FileSize & (~(_256K - 1));
        //
        // we are not allowed to shrink in shared mode.
        //
	    ASSERT_HIVE_WRITER_LOCK_OWNED((PCMHIVE)Hive);

        while( Offset < OldFileSize ) {
            CmpUnmapCmViewSurroundingOffset((PCMHIVE)Hive,Offset);
            Offset += CM_VIEW_SIZE;
        }

        //
        // we need to take extra precaution here and unmap the very last view too
        //
        
        FileOffset.HighPart = 0;
        FileOffset.LowPart = FileSize;
        //
        // This is a shrink; Inform cache manager of the change of the size
        //
        CcPurgeCacheSection( ((PCMHIVE)Hive)->FileObject->SectionObjectPointer, (PLARGE_INTEGER)(((ULONG_PTR)(&FileOffset)) + 1), 
                            OldFileSize - FileSize, FALSE );

        //
        // Flush out this view to clear out the Cc dirty hints
        //
        CcFlushCache( ((PCMHIVE)Hive)->FileObject->SectionObjectPointer, (PLARGE_INTEGER)(((ULONG_PTR)(&FileOffset)) + 1),/*we are private writers*/
                            OldFileSize - FileSize,NULL);

    }
    
    return Status;
}
_IRQL_requires_same_
inline VOID KrnlHlprClassifyDataReleaseLocalCopy(_Inout_ CLASSIFY_DATA* pClassifyData)
{
#if DBG

   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprClassifyDataReleaseLocalCopy()\n");

#endif /// DBG
   
   NT_ASSERT(pClassifyData);

   KrnlHlprFwpsClassifyOutDestroyLocalCopy((FWPS_CLASSIFY_OUT**)&(pClassifyData->pClassifyOut));

   pClassifyData->flowContext = 0;

   KrnlHlprFwpsFilterDestroyLocalCopy((FWPS_FILTER**)&(pClassifyData->pFilter));

#if(NTDDI_VERSION >= NTDDI_WIN7)
   
      if(pClassifyData->classifyContextHandle)
         FwpsReleaseClassifyHandle(pClassifyData->classifyContextHandle);
   
#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

   if(pClassifyData->pPacket)
   {
      if(pClassifyData->pClassifyValues)
      {
         if(pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 ||
            pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD ||
            pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V6 ||
            pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD)
            KrnlHlprFwpsStreamCalloutIOPacketDestroyLocalCopy((FWPS_STREAM_CALLOUT_IO_PACKET**)&(pClassifyData->pPacket));
         else if(pClassifyData->chainedNBL)
         {
            BOOLEAN isDispatch	   = (KeGetCurrentIrql() == DISPATCH_LEVEL) ? TRUE : FALSE;
            UINT32  numChainedNBLs  = pClassifyData->numChainedNBLs;

            for(NET_BUFFER_LIST* pCurrentNBL = (NET_BUFFER_LIST*)pClassifyData->pPacket;
                pCurrentNBL &&
                numChainedNBLs;
                numChainedNBLs--)
            {
               NET_BUFFER_LIST* pNextNBL = NET_BUFFER_LIST_NEXT_NBL(pCurrentNBL);

               FwpsDereferenceNetBufferList(pCurrentNBL,
                                            isDispatch);

               pCurrentNBL = pNextNBL;

#if DBG

               InterlockedDecrement64((LONG64*)&(g_OutstandingNBLReferences));

#endif /// DBG

            }
         }
         else
         {
            BOOLEAN isDispatch = (KeGetCurrentIrql() == DISPATCH_LEVEL) ? TRUE : FALSE;

            FwpsDereferenceNetBufferList((NET_BUFFER_LIST*)pClassifyData->pPacket,
                                         isDispatch);

#if DBG

            InterlockedDecrement64((LONG64*)&(g_OutstandingNBLReferences));

#endif /// DBG

         }
      }

      pClassifyData->pPacket = 0;
   }

   KrnlHlprFwpsIncomingMetadataValuesDestroyLocalCopy((FWPS_INCOMING_METADATA_VALUES**)&(pClassifyData->pMetadataValues));

   if(pClassifyData->pClassifyValues)
      KrnlHlprFwpsIncomingValuesDestroyLocalCopy((FWPS_INCOMING_VALUES**)&(pClassifyData->pClassifyValues));

   RtlZeroMemory(pClassifyData,
                 sizeof(CLASSIFY_DATA));

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprClassifyDataReleaseLocalCopy()\n");

#endif /// DBG
   
   return;
}
NTSTATUS TriggerPendAuthorizationOutOfBand(_In_ const FWPS_INCOMING_VALUES* pClassifyValues,
                                           _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata,
                                           _Inout_opt_ VOID* pLayerData,
                                           _In_opt_ const VOID* pClassifyContext,
                                           _In_ const FWPS_FILTER* pFilter,
                                           _In_ UINT64 flowContext,
                                           _In_ FWPS_CLASSIFY_OUT* pClassifyOut,
                                           _Inout_opt_ INJECTION_DATA* pInjectionData,
                                           _Inout_ PEND_DATA* pPendData,
                                           _In_ PC_PEND_AUTHORIZATION_DATA* pPCData)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> TriggerPendAuthorizationOutOfBand()\n");

#endif /// DBG
   
   NT_ASSERT(pClassifyValues);
   NT_ASSERT(pMetadata);
   NT_ASSERT(pFilter);
   NT_ASSERT(pClassifyOut);
   NT_ASSERT(pPendData);
   NT_ASSERT(pPCData);
 
   NTSTATUS       status        = STATUS_SUCCESS;
   CLASSIFY_DATA* pClassifyData = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy

   status = KrnlHlprClassifyDataCreateLocalCopy(&pClassifyData,
                                                pClassifyValues,
                                                pMetadata,
                                                pLayerData,
                                                pClassifyContext,
                                                pFilter,
                                                flowContext,
                                                pClassifyOut);
   HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

   if(pPCData->useWorkItems ||
      pPCData->delay)
   {
      /// introducing the delay requires PASSIVE_LEVEL, so force use of a Work Item
      status = KrnlHlprWorkItemQueue(g_pWDMDevice,
                                     PendAuthorizationWorkItemRoutine,
                                     pClassifyData,
                                     pPendData,
                                     (VOID*)pInjectionData);
   }
   else
   {
      if(pPCData->useThreadedDPC)
         status = KrnlHlprThreadedDPCQueue(PendAuthorizationDeferredProcedureCall,
                                           pClassifyData,
                                           pPendData,
                                           pInjectionData);
      else
         status = KrnlHlprDPCQueue(PendAuthorizationDeferredProcedureCall,
                                   pClassifyData,
                                   pPendData,
                                   pInjectionData);
   }

   HLPR_BAIL_ON_FAILURE(status);

   pClassifyOut->actionType = FWP_ACTION_BLOCK;

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS)
   {
      if(pClassifyData)
         KrnlHlprClassifyDataDestroyLocalCopy(&pClassifyData);
   }

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- TriggerPendAuthorizationOutOfBand() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
}
Example #4
0
///////////////////////////////////////////////////////////////////////////////
///
/// Driver entry
///
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT  DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
	NTSTATUS Status;
	UNICODE_STRING NtDeviceName = RTL_CONSTANT_STRING(QD_NT_DEVICE_NAME);
	UNICODE_STRING DosDevicesLinkName = RTL_CONSTANT_STRING(QD_DOS_DEVICES_LINK_NAME);
	BOOLEAN SymLinkCreated = FALSE;
	PQD_COMM_CONTROL_DEVICE_EXTENSION controlExt;

	UNREFERENCED_PARAMETER(RegistryPath);

	// Request NX Non-Paged Pool when available
	ExInitializeDriverRuntime(DrvRtPoolNxOptIn);

	DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "QuietDragon: DriverEntry: Driver loaded\n");

	//
	// Initialize globals.
	//

	//
	// Create our device object.
	//
	// TODO Consider using IoCreateDeviceSecure 
	Status = IoCreateDevice(
		DriverObject,                 // pointer to driver object
		sizeof(QD_COMM_CONTROL_DEVICE_EXTENSION),  // device extension size
		&NtDeviceName,                // device name
		FILE_DEVICE_UNKNOWN,          // device type
		0,                            // device characteristics
		FALSE,                        // not exclusive
		&g_CommDeviceObject);         // returned device object pointer
	if (!NT_SUCCESS(Status))
	{
		goto Exit;
	}

	TD_ASSERT(g_CommDeviceObject == DriverObject->DeviceObject);

	//
	// Set dispatch routines.
	//
	DriverObject->MajorFunction[IRP_MJ_CREATE] = TdDeviceCreate;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = TdDeviceClose;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TdDeviceCleanup;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TdDeviceControl;
	DriverObject->DriverUnload = TdDeviceUnload;


	//
	// Set up the device extension
	//
	controlExt = (PQD_COMM_CONTROL_DEVICE_EXTENSION)g_CommDeviceObject->DeviceExtension;
	controlExt->MagicNumber = QD_COMM_CONTROL_EXTENSION_MAGIC_NUMBER;
	InitializeListHead(&controlExt->ProcessQueue);
	ExInitializeFastMutex(&controlExt->ProcessQueueLock);
	InitializeListHead(&controlExt->RequestQueue);
	ExInitializeFastMutex(&controlExt->RequestQueueLock);
	ExInitializeFastMutex(&controlExt->DecisionDataLock);

	controlExt->DecisionData = (PCONTROL_PROC_INTERNAL)ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROL_PROC_INTERNAL)*QD_MAX_PROCS, 'SRdd');
	RtlZeroMemory(controlExt->DecisionData, sizeof(CONTROL_PROC_INTERNAL)*QD_MAX_PROCS);

	// Init DecisionData
	for (USHORT i = 0; i < QD_MAX_PROCS; i++) {
		PCONTROL_PROC_INTERNAL control_proc = &(controlExt->DecisionData[i]);
		control_proc->StartTime.QuadPart = 0;
		KeInitializeEvent(&(control_proc->DecisionEvent), NotificationEvent, FALSE);
	}

	//
	// Create a link in the Win32 namespace.
	//
	Status = IoCreateSymbolicLink(&DosDevicesLinkName, &NtDeviceName);
	if (!NT_SUCCESS(Status))
	{
		goto Exit;
	}

	SymLinkCreated = TRUE;

	//
	// Set process create routines.
	//
	Status = PsSetCreateProcessNotifyRoutineEx(
		MyCreateProcessNotifyRoutine,
		FALSE
		);
	if (!NT_SUCCESS(Status))
	{
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "QuietDragon: DriverEntry: PsSetCreateProcessNotifyRoutineEx returned 0x%x\n", Status);
		goto Exit;
	}

	gProcessNotifyRoutine_isSet = TRUE;


Exit:

	if (!NT_SUCCESS(Status))
	{
		if (gProcessNotifyRoutine_isSet == TRUE)
		{
			Status = PsSetCreateProcessNotifyRoutineEx(
				MyCreateProcessNotifyRoutine,
				TRUE
				);
			TD_ASSERT(Status == STATUS_SUCCESS);

			gProcessNotifyRoutine_isSet = FALSE;
		}

		if (SymLinkCreated == TRUE)
		{
			IoDeleteSymbolicLink(&DosDevicesLinkName);
		}

		if (g_CommDeviceObject != NULL)
		{
			IoDeleteDevice(g_CommDeviceObject);
		}
	}

	return Status;
}
NTSTATUS KrnlHlprClassifyDataAcquireLocalCopy(_Inout_ CLASSIFY_DATA* pClassifyData,
                                              _In_ const FWPS_INCOMING_VALUES* pClassifyValues,
                                              _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata,
                                              _In_opt_ VOID* pPacket,
                                              _In_opt_ const VOID* pClassifyContext,
                                              _In_ const FWPS_FILTER* pFilter,
                                              _In_ const UINT64 flowContext,
                                              _In_ FWPS_CLASSIFY_OUT* pClassifyOut)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprClassifyDataAcquireLocalCopy()\n");

#endif /// DBG
   
   NT_ASSERT(pClassifyData);
   NT_ASSERT(pClassifyValues);
   NT_ASSERT(pMetadata);
   NT_ASSERT(pFilter);
   NT_ASSERT(pClassifyOut);

   NTSTATUS status = STATUS_SUCCESS;

   pClassifyData->pClassifyValues = KrnlHlprFwpsIncomingValuesCreateLocalCopy(pClassifyValues);
   HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pClassifyValues,
                                         status);

   pClassifyData->pMetadataValues = KrnlHlprFwpsIncomingMetadataValuesCreateLocalCopy(pMetadata);
   HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pMetadataValues,
                                         status);

   if(pPacket)
   {
      if(pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 ||
         pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD ||
         pClassifyValues->layerId == FWPS_LAYER_STREAM_V6 ||
         pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD)
      {
         pClassifyData->pPacket = KrnlHlprFwpsStreamCalloutIOPacketCreateLocalCopy((FWPS_STREAM_CALLOUT_IO_PACKET*)pPacket);
         HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pPacket,
                                               status);
      }

#if(NTDDI_VERSION >= NTDDI_WIN7)

      /// LayerData at the FWPM_LAYER_ALE_{BIND/CONNECT}_REDIRECT_V{4/6} is obtained via KrnlHlprRedirectDataCreate()
      else if(pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 ||
              pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V6 ||
              pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V4 ||
              pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V6)
      {
         pClassifyData->pPacket = 0;
      }

#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

      else
      {
         if(NET_BUFFER_LIST_NEXT_NBL((NET_BUFFER_LIST*)pPacket))
         {
            pClassifyData->chainedNBL     = TRUE;
            pClassifyData->numChainedNBLs = 1;
         }

         if(pClassifyData->chainedNBL &&
            (
            /// The IPPACKET and IPFORWARD Layers allow for Fragment Grouping if the option is enabled
            pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 ||
            pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6 ||
            pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 ||
            pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6

#if(NTDDI_VERSION >= NTDDI_WIN8)

            /// The NDIS layers allow for batched NBLs provided the callout was registered with FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY set
            ||
            pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET ||
            pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET ||
            pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_NATIVE ||
            pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_NATIVE ||
            pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_ETHERNET ||
            pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_ETHERNET

#endif /// (NTDDI_VERSION >= NTDDI_WIN8)

            ))
         {
            for(NET_BUFFER_LIST* pCurrentNBL = (NET_BUFFER_LIST*)pPacket;
                pCurrentNBL;
                pClassifyData->numChainedNBLs++)
            {
               NET_BUFFER_LIST* pNextNBL = NET_BUFFER_LIST_NEXT_NBL(pCurrentNBL);

               FwpsReferenceNetBufferList(pCurrentNBL,
                                          TRUE);

               pCurrentNBL = pNextNBL;

#if DBG

               InterlockedIncrement64((LONG64*)&(g_OutstandingNBLReferences));

#endif /// DBG

            }

            pClassifyData->pPacket = pPacket;
         }
         else
         {
            /// Otherwise we expect to receive a single NBL
            NT_ASSERT(NET_BUFFER_LIST_NEXT_NBL((NET_BUFFER_LIST*)pPacket) == 0);

            FwpsReferenceNetBufferList((NET_BUFFER_LIST*)pPacket,
                                       TRUE);

            pClassifyData->pPacket = pPacket;

#if DBG
         
            InterlockedIncrement64((LONG64*)&(g_OutstandingNBLReferences));
         
#endif /// DBG

         }
      }
   }

#if(NTDDI_VERSION >= NTDDI_WIN7)
   
      if(pClassifyContext)
      {
         /// ClassifyHandle for these layers is obtained in REDIRECT_DATA
         if(pClassifyValues->layerId != FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 &&
            pClassifyValues->layerId != FWPS_LAYER_ALE_CONNECT_REDIRECT_V6 &&
            pClassifyValues->layerId != FWPS_LAYER_ALE_BIND_REDIRECT_V4 &&
            pClassifyValues->layerId != FWPS_LAYER_ALE_BIND_REDIRECT_V6)
         {
            status = FwpsAcquireClassifyHandle((VOID*)pClassifyContext,
                                               0,
                                               &(pClassifyData->classifyContextHandle));
            HLPR_BAIL_ON_FAILURE(status);
         }
      }
#else
   
      UNREFERENCED_PARAMETER(pClassifyContext);
   
#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

   if(pFilter)
   {
      pClassifyData->pFilter = KrnlHlprFwpsFilterCreateLocalCopy(pFilter);
      HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pFilter,
                                            status);
   }

   pClassifyData->flowContext = flowContext;

   if(pClassifyOut)
   {
      pClassifyData->pClassifyOut = KrnlHlprFwpsClassifyOutCreateLocalCopy(pClassifyOut);
      HLPR_BAIL_ON_NULL_POINTER_WITH_STATUS(pClassifyData->pClassifyOut,
                                            status);
   }

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS)
      KrnlHlprClassifyDataReleaseLocalCopy(pClassifyData);

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprClassifyDataAcquireLocalCopy() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
}
Example #6
0
File: Pnp.c Project: uri247/pmgmt
NTSTATUS
SwdmDispatchPnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    IO_STACK_LOCATION* pStk;
    DEVICE_EXTENSION* pCtx;
	ULONG MinorCode;
	NTSTATUS Status = STATUS_SUCCESS;

	DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MJ_PNP Received : Begin\n" );

	pStk = IoGetCurrentIrpStackLocation(Irp);
	pCtx = (DEVICE_EXTENSION*)DeviceObject->DeviceExtension;
	IoAcquireRemoveLock( &pCtx->RemoveLock, Irp);
	MinorCode = pStk->MinorFunction;

    DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Minor code: 0x%x\n", MinorCode );

	switch( MinorCode )
	{
	case IRP_MN_START_DEVICE:
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_START_DEVICE Received : Begin\r\n");
		Status = StartDevice( DeviceObject, Irp );
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_START_DEVICE Received : End\r\n");
		break;
	case IRP_MN_STOP_DEVICE:
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_STOP_DEVICE Received : Begin\r\n");
		Status = StopDevice( DeviceObject, Irp );
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_STOP_DEVICE Received : End\r\n");
		break;
	case IRP_MN_REMOVE_DEVICE:
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_REMOVE_DEVICE Received : Begin\r\n");
		Status = RemoveDevice( DeviceObject, Irp );
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_REMOVE_DEVICE Received : End\r\n");
		break;
	case IRP_MN_QUERY_CAPABILITIES :
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_CAPABILITIES Received : Begin\r\n");
		Status = QueryCapability(
			DeviceObject,
			Irp
		);
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_CAPABILITIES Received : End\r\n");
		break;
    case IRP_MN_QUERY_BUS_INFORMATION:
        DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_BUS_INFORMATION Received : Begin\n");
        Status = QueryBus( DeviceObject, Irp );
        break;

	default:
		break;
	}
	IoReleaseRemoveLock( &pCtx->RemoveLock, Irp);
	
	if (NT_SUCCESS(Status))
    {
	  CompleteRequest(
		Irp, 
		STATUS_SUCCESS, 
		0);
    }

	DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MJ_PNP Received : End\r\n");

	return Status;
}
Example #7
0
File: sub.c Project: airhigh/wdrbd
void _printk(const char * func, const char * format, ...)
{
	int ret = 0;
	va_list args;

	char * buf = (char *) ExAllocateFromNPagedLookasideList(&drbd_printk_msg);
	if (!buf)
	{
		return;
	}
	RtlZeroMemory(buf, MAX_ELOG_BUF);

	va_start(args, format);
	ret = vsprintf(buf, format, args); // DRBD_DOC: improve vsnprintf 
	va_end(args);

	int length = strlen(buf);
	if (length > MAX_ELOG_BUF)
	{
		length = MAX_ELOG_BUF - 1;
		buf[MAX_ELOG_BUF - 1] = 0;
	}
	else
	{
		// TODO: chekc min?
	}

	ULONG msgid = PRINTK_INFO;
	int level_index = format[1] - '0';
	int printLevel = 0;
	CHAR szTempBuf[MAX_ELOG_BUF] = "";
	BOOLEAN bSysEventLog = FALSE;
	BOOLEAN bServiceLog = FALSE;
	BOOLEAN bDbgLog = FALSE;
	extern atomic_t g_syslog_lv_min;
	extern atomic_t g_svclog_lv_min;
	extern atomic_t g_dbglog_lv_min;

	ASSERT((level_index >= 0) && (level_index < 8));
	
#ifdef _WIN32_WPP
	DoTraceMessage(TRCINFO, "%s", buf);
	WriteEventLogEntryData(msgids[level_index], 0, 0, 1, L"%S", buf + 3);
	DbgPrintEx(FLTR_COMPONENT, DPFLTR_INFO_LEVEL, "WDRBD_INFO: [%s] %s", func, buf + 3);
	ExFreeToNPagedLookasideList(&drbd_printk_msg, buf);
#else
	// to write system event log.
	if (level_index <= atomic_read(&g_syslog_lv_min))
		bSysEventLog = TRUE;
	// to send to drbd service.	
	if (level_index <= atomic_read(&g_svclog_lv_min))
		bServiceLog = TRUE;
	// to print through debugger.
	if (level_index <= atomic_read(&g_dbglog_lv_min))
		bDbgLog = TRUE;

	// nothing to log.
	if (!bSysEventLog &&
		!bServiceLog &&
		!bDbgLog)
	{
		ExFreeToNPagedLookasideList(&drbd_printk_msg, buf);
		return;
	}

	if (bSysEventLog)
	{
		save_to_system_event(buf, length, level_index);
	}

	switch (level_index)
	{
	case KERN_EMERG_NUM:
	case KERN_ALERT_NUM:
	case KERN_CRIT_NUM:
		printLevel = DPFLTR_ERROR_LEVEL;
		sprintf(szTempBuf, "<%d>%s: [%s] %s", level_index, "WDRBD_FATA", func, buf + 3);
		break;
	case KERN_ERR_NUM:
		printLevel = DPFLTR_ERROR_LEVEL;
		sprintf(szTempBuf, "<%d>%s: [%s] %s", level_index, "WDRBD_ERRO", func, buf + 3);
		break;
	case KERN_WARNING_NUM:
		printLevel = DPFLTR_WARNING_LEVEL;
		sprintf(szTempBuf, "<%d>%s: [%s] %s", level_index, "WDRBD_WARN", func, buf + 3);
		break;
	case KERN_NOTICE_NUM:
	case KERN_INFO_NUM:
		printLevel = DPFLTR_INFO_LEVEL;
		sprintf(szTempBuf, "<%d>%s: [%s] %s", level_index, "WDRBD_INFO", func, buf + 3);
		break;
	case KERN_DEBUG_NUM:
		printLevel = DPFLTR_TRACE_LEVEL;
		sprintf(szTempBuf, "<%d>%s: [%s] %s", level_index, "WDRBD_TRAC", func, buf + 3);
		break;
	default:
		printLevel = DPFLTR_TRACE_LEVEL;
		sprintf(szTempBuf, "<%d>%s: [%s] %s", level_index, "WDRBD_UNKN", func, buf + 3);
		break;
	}

	strcpy_s(buf, MAX_ELOG_BUF, szTempBuf);

	if (bDbgLog)
		DbgPrintEx(FLTR_COMPONENT, printLevel, buf + 3);

#ifdef _WIN32_LOGLINK
	if (FALSE == bServiceLog ||
		FALSE == LogLink_IsUsable() ||
		STATUS_SUCCESS != LogLink_QueueBuffer(buf))
	{
		// buf will be freed by loglink sender thread if it's queued, otherwise free it here.
		ExFreeToNPagedLookasideList(&drbd_printk_msg, buf);
	}
#else
    // WriteEventLogEntryData(msgids[level_index], 0, 0, 1, L"%S", buf + 3); //old style
    DbgPrintEx(FLTR_COMPONENT, DPFLTR_INFO_LEVEL, "WDRBD_INFO: [%s] %s", func, buf + 3);

	ExFreeToNPagedLookasideList(&drbd_printk_msg, buf);
#endif
#endif
}
Example #8
0
NTSTATUS
DriverEntry (
    _In_ PDRIVER_OBJECT  DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine is called by the operating system to initialize the driver. 
    It allocates a device object, initializes the supported Io callbacks, and
    creates a symlink to make the device accessible to Win32.

    It gets the registry callback version and stores it in the global
    variables g_MajorVersion and g_MinorVersion. It also calls
    CreateKTMResourceManager to create a resource manager that is used in 
    the transaction samples.

Arguments:
    
    DriverObject - Supplies the system control object for this test driver.

    RegistryPath - The string location of the driver's corresponding services 
                   key in the registry.

Return value:

    Success or appropriate failure code.

--*/
{
    NTSTATUS Status;
    UNICODE_STRING NtDeviceName;
    UNICODE_STRING DosDevicesLinkName;
    UNICODE_STRING DeviceSDDLString;

    UNREFERENCED_PARAMETER(RegistryPath);

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 
               DPFLTR_ERROR_LEVEL,
               "RegFltr: DriverEntry()\n");

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 
               DPFLTR_ERROR_LEVEL,
               "RegFltr: Use ed nt!Kd_IHVDRIVER_Mask 8 to enable more detailed printouts\n");

    //
    // Create our device object.
    //

    RtlInitUnicodeString(&NtDeviceName, NT_DEVICE_NAME);
    RtlInitUnicodeString(&DeviceSDDLString, DEVICE_SDDL);

    // TODO(H): 看下这个函数
    Status = IoCreateDeviceSecure(
                            DriverObject,                 // pointer to driver object
                            0,                            // device extension size
                            &NtDeviceName,                // device name
                            FILE_DEVICE_UNKNOWN,          // device type
                            0,                            // device characteristics
                            TRUE,                         // not exclusive
                            &DeviceSDDLString,            // SDDL string specifying access
                            NULL,                         // device class guid
                            &g_DeviceObj);                // returned device object pointer

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    //
    // Set dispatch routines.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DeviceCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DeviceClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]        = DeviceCleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
    DriverObject->DriverUnload                         = DeviceUnload;

    //
    // Create a link in the Win32 namespace.
    //
    
    RtlInitUnicodeString(&DosDevicesLinkName, DOS_DEVICES_LINK_NAME);

    Status = IoCreateSymbolicLink(&DosDevicesLinkName, &NtDeviceName);

    if (!NT_SUCCESS(Status)) {
        IoDeleteDevice(DriverObject->DeviceObject);
        return Status;
    }

    //
    // Get callback version.
    //

    // TODO(H): 
    CmGetCallbackVersion(&g_MajorVersion, &g_MinorVersion);
    InfoPrint("Callback version %u.%u", g_MajorVersion, g_MinorVersion);

    //
    // Some variations depend on knowing if the OS is win8 or above
    //
    
    DetectOSVersion();

    //
    // Set up KTM resource manager and pass in RMCallback as our
    // callback routine.
    //

    Status = CreateKTMResourceManager(RMCallback, NULL);

    if (NT_SUCCESS(Status)) {
        g_RMCreated = TRUE;
    }

    //
    // Initialize the callback context list
    //

    InitializeListHead(&g_CallbackCtxListHead);
    ExInitializeFastMutex(&g_CallbackCtxListLock);
    g_NumCallbackCtxListEntries = 0;

    return STATUS_SUCCESS;
    
}
NTSTATUS KrnlHlprNDISPoolDataPopulate(_Inout_ NDIS_POOL_DATA* pNDISPoolData,
                                      _In_opt_ UINT32 memoryTag)             /* WFPSAMPLER_NDIS_POOL_TAG */
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprNDISPoolDataPopulate()\n");

#endif /// DBG
   
   NT_ASSERT(pNDISPoolData);

   NTSTATUS                        status            = STATUS_SUCCESS;
   NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParameters = {0};
   NET_BUFFER_POOL_PARAMETERS      nbPoolParameters  = {0};

   pNDISPoolData->ndisHandle = NdisAllocateGenericObject(0,
                                                         memoryTag,
                                                         0);
   if(pNDISPoolData->ndisHandle == 0)
   {
      status = STATUS_INVALID_HANDLE;

      DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                 DPFLTR_ERROR_LEVEL,
                 " !!!! KrnlHlprNDISPoolDataPopulate : NdisAllocateGenericObject() [status: %#x]\n",
                 status);

      HLPR_BAIL;
   }

   nblPoolParameters.Header.Type        = NDIS_OBJECT_TYPE_DEFAULT;
   nblPoolParameters.Header.Revision    = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
   nblPoolParameters.Header.Size        = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
   nblPoolParameters.fAllocateNetBuffer = TRUE;
   nblPoolParameters.DataSize           = 0;
   nblPoolParameters.PoolTag            = memoryTag;

   pNDISPoolData->nblPoolHandle = NdisAllocateNetBufferListPool(pNDISPoolData->ndisHandle,
                                                                &nblPoolParameters);
   if(pNDISPoolData->nblPoolHandle == 0)
   {
      status = STATUS_INVALID_HANDLE;

      DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                 DPFLTR_ERROR_LEVEL,
                 " !!!! KrnlHlprNDISPoolDataPopulate : NdisAllocateNetBufferListPool() [status: %#x]\n",
                 status);

      HLPR_BAIL;
   }

   nbPoolParameters.Header.Type     = NDIS_OBJECT_TYPE_DEFAULT;
   nbPoolParameters.Header.Revision = NET_BUFFER_POOL_PARAMETERS_REVISION_1;
   nbPoolParameters.Header.Size     = NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1;
   nbPoolParameters.PoolTag         = memoryTag;
   nbPoolParameters.DataSize        = 0;

   pNDISPoolData->nbPoolHandle = NdisAllocateNetBufferPool(pNDISPoolData->ndisHandle,
                                                           &nbPoolParameters);
   if(pNDISPoolData->nbPoolHandle == 0)
   {
      status = STATUS_INVALID_HANDLE;

      DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                 DPFLTR_ERROR_LEVEL,
                 " !!!! KrnlHlprNDISPoolDataPopulate : NdisAllocateNetBufferPool() [status: %#x]\n",
                 status);

      HLPR_BAIL;
   }

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS)
      KrnlHlprNDISPoolDataPurge(pNDISPoolData);

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprNDISPoolDataPopulate()\n");

#endif /// DBG
   
   return status;
}
Example #10
0
File: Device.c Project: uri247/kmdf
NTSTATUS
SmplDeviceCreateDevice(
    _Inout_ PWDFDEVICE_INIT DeviceInit
    )
/*++

Routine Description:

    Worker routine called to create a device and its software resources.

Arguments:

    DeviceInit - Pointer to an opaque init structure. Memory for this
                    structure will be freed by the framework when the WdfDeviceCreate
                    succeeds. So don't access the structure after that point.

Return Value:

    NTSTATUS

--*/
{
    WDF_OBJECT_ATTRIBUTES deviceAttributes;
    PDEVICE_CONTEXT deviceContext;
    WDF_PNPPOWER_EVENT_CALLBACKS PnpPowerEventCallbacks;
    WDFDEVICE device;
    NTSTATUS status;

    PAGED_CODE();

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
    deviceAttributes.SynchronizationScope = WdfSynchronizationScopeQueue;

    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PnpPowerEventCallbacks);
    PnpPowerEventCallbacks.EvtDevicePrepareHardware = SmplDeviceEvtPrepareHardware;
    PnpPowerEventCallbacks.EvtDeviceReleaseHardware = SmplDeviceEvtReleaseHardware;
    PnpPowerEventCallbacks.EvtDeviceD0Entry = SmplDeviceEvtD0Entry;
    PnpPowerEventCallbacks.EvtDeviceD0Exit = SmplDeviceEvtD0Exit;
    WdfDeviceInitSetPnpPowerEventCallbacks( DeviceInit, &PnpPowerEventCallbacks);

    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    if (NT_SUCCESS(status)) 
    {   //
        // Get the device context and initialize it. DeviceGetContext is an
        // inline function generated by WDF_DECLARE_CONTEXT_TYPE macro in the
        // device.h header file. This function will do the type checking and return
        // the device context. If you pass a wrong object  handle
        // it will return NULL and assert if run under framework verifier mode.
        //
        deviceContext = DeviceGetContext(device);

        //
        // Create a device interface so that applications can find and talk
        // to us.
        //
        status = WdfDeviceCreateDeviceInterface(device,
                                                &GUID_DEVINTERFACE_SMPLDEVICE,
                                                NULL);
        if (NT_SUCCESS(status)) 
        {   //
            // Initialize the I/O Package and any Queues
            //
            status = SmplDeviceQueueInitialize(device);
        }

        if (NT_SUCCESS(status)) {
            WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS PowerPolicyIdleSettings;
            WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&PowerPolicyIdleSettings, IdleCannotWakeFromS0);
            PowerPolicyIdleSettings.IdleTimeoutType = SystemManagedIdleTimeout;

            status = WdfDeviceAssignS0IdleSettings(device, &PowerPolicyIdleSettings);
            if (!NT_SUCCESS(status)) 
            {
                DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"WdfDeviceAssignS0IdleSettings failed! 0x%x\n", status);
            }
        }

        if (NT_SUCCESS(status)) {
            SmplPoFxSingleComponentInitialize(device);
        }

        if (NT_SUCCESS(status)) 
        {
            WDFINTERRUPT Interrupt;
            WDF_INTERRUPT_CONFIG Configuration;
            WDF_INTERRUPT_CONFIG_INIT(&Configuration, SmplInterruptEvtIsr, SmplInterruptEvtDpc);
            Configuration.EvtInterruptEnable = SmplInterruptEvtEnable;
            Configuration.EvtInterruptDisable = SmplInterruptEvtDisable;
            status = WdfInterruptCreate(device,
                                        &Configuration,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &Interrupt);
            if (!NT_SUCCESS(status)) 
            {
                DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234, "WdfInterruptCreate failed! 0x%x\n", status);
            }
        }

    }

    return status;
}
NTSTATUS KrnlHlprThreadedDPCQueue(_In_ KDEFERRED_ROUTINE* pDPCFn,
                                  _In_ CLASSIFY_DATA* pClassifyData,
                                  _In_ REDIRECT_DATA* pRedirectData,
                                  _In_opt_ VOID* pContext)           /* 0 */
{
#if DBG

   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprThreadedDPCQueue()\n");

#endif /// DBG

   NT_ASSERT(pDPCFn);
   NT_ASSERT(pClassifyData);
   NT_ASSERT(pRedirectData);

   NTSTATUS  status   = STATUS_SUCCESS;
   DPC_DATA* pDPCData = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pDPCData will be freed by caller

   status = KrnlHlprDPCDataCreate(&pDPCData,
                                  pClassifyData,
                                  pRedirectData,
                                  pContext);
   HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

   KeInitializeThreadedDpc(&(pDPCData->kdpc),
                           pDPCFn,
                           0);

   KeInsertQueueDpc(&(pDPCData->kdpc),
                    pDPCData,
                    0);

   HLPR_BAIL_LABEL:

#pragma warning(push)
#pragma warning(disable: 6001) /// pDPCData initialized with call to KrnlHlprDPCDataCreate

   if(status != STATUS_SUCCESS &&
      pDPCData)
      KrnlHlprDPCDataDestroy(&pDPCData);

#pragma warning(pop)

#if DBG

   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprThreadedDPCQueue() [status: %#x]\n",
              status);

#endif /// DBG

   return status;
}
Example #12
0
BOOLEAN
CmpFileFlush (
    PHHIVE          Hive,
    ULONG           FileType,
    PLARGE_INTEGER  FileOffset,
    ULONG           Length
    )
/*++

Routine Description:

    This routine performs a flush on a file handle.

Arguments:

    Hive - Hive we are doing I/O for

    FileType - which supporting file to use

    FileOffset - If this parameter is supplied (not NULL), then only the
                 byte range specified by FileOffset and Length are flushed.

    Length - Defines the length of the byte range to flush, starting at
             FileOffset.  This parameter is ignored if FileOffset is
             specified as NULL.
    

Return Value:

    FALSE if failure
    TRUE if success

Note: 
    
    FileOffset and Length are only taken into account when FileType == HFILE_TYPE_PRIMARY
    and the hive uses the mapped-views method.
--*/
{
    NTSTATUS        status;
    IO_STATUS_BLOCK IoStatus;
    PCMHIVE         CmHive;
    HANDLE          FileHandle;

    ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0);
    CmHive = (PCMHIVE)Hive;
    FileHandle = CmHive->FileHandles[FileType];
    if (FileHandle == NULL) {
        return TRUE;
    }

    if (CmpNoWrite) {
        return TRUE;
    }

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_IO,"CmpFileFlush:\n\tHandle = %08lx\n", FileHandle));

    ASSERT_PASSIVE_LEVEL();


    if( HiveWritesThroughCache(Hive,FileType) == TRUE ) {       
        //
        // OK, we need to flush using CcFlushCache
        //
        CcFlushCache (CmHive->FileObject->SectionObjectPointer,(PLARGE_INTEGER)((ULONG_PTR)FileOffset + 1)/*we are private writers*/,Length,&IoStatus);
        status = IoStatus.Status;
	    if( !NT_SUCCESS(status) ) {
			goto Error;
		}
    } 
    //
    // we have to do that regardless, to make sure the disk cache makes it to the disk.
    //
    status = ZwFlushBuffersFile(
                FileHandle,
                &IoStatus
                );

    if (NT_SUCCESS(status)) {
        ASSERT(IoStatus.Status == status);
        return TRUE;
    } else {
Error:
        //
        // set debugging info
        //
        CmRegistryIODebug.Action = CmpIoFileFlush;
        CmRegistryIODebug.Handle = FileHandle;
        CmRegistryIODebug.Status = status;

#if DBG
        DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"CmpFileFlush:\tFailure1: status = %08lx  IoStatus = %08lx\n",status,IoStatus.Status);
#endif
        return FALSE;
    }
}
Example #13
0
BOOLEAN
CmpFileWrite(
    PHHIVE              Hive,
    ULONG               FileType,
    PCMP_OFFSET_ARRAY   offsetArray,
    ULONG               offsetArrayCount,
    PULONG              FileOffset
    )
/*++

Routine Description:

    This routine writes an array of buffers out to a file.

    It is environment specific.

    NOTE:   We assume the handle is opened for asynchronous access,
            and that we, and not the IO system, are keeping the
            offset pointer.

    NOTE:   Only 32bit offsets are supported, even though the underlying
            IO system on NT supports 64 bit offsets.

Arguments:

    Hive - Hive we are doing I/O for

    FileType - which supporting file to use

    offsetArray - array of structures where each structure holds a 32bit offset
                  into the Hive file and pointer the a buffer written to that
                  file offset.

    offsetArrayCount - number of elements in the offsetArray.

    FileOffset - returns the file offset after the last write to the file.

Return Value:

    FALSE if failure
    TRUE if success

--*/
{
    NTSTATUS        status;
    LARGE_INTEGER   Offset;
    PCMHIVE         CmHive;
    HANDLE          FileHandle;
    ULONG           LengthToWrite;
    LONG            WaitBufferCount = 0;
    LONG            idx;
    ULONG           arrayCount = 0;
    PVOID           DataBuffer = NULL;      // W4 only
    ULONG           DataLength;
    BOOLEAN         ret_val = TRUE;
    PCM_WRITE_BLOCK WriteBlock = NULL;

    if (CmpNoWrite) {
        return TRUE;
    }

    ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0);
    CmHive = (PCMHIVE)Hive;
    FileHandle = CmHive->FileHandles[FileType];
    if (FileHandle == NULL) {
        return TRUE;
    }

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_IO,"CmpFileWrite:\n"));
    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_IO,"\tHandle=%08lx  ", FileHandle));

    //
    // decide whether we wait for IOs to complete or just issue them and
    // rely on the CcFlushCache to do the job
    //
    
    // Bring pages being written into memory first to allow disk to write
    // buffer contiguously.
    try {
        for (idx = 0; (ULONG) idx < offsetArrayCount; idx++) {
            char * start = offsetArray[idx].DataBuffer;
            char * end = (char *) start + offsetArray[idx].DataLength;
            while (start < end) {
                // perftouchbuffer globally declared so that compiler won't try
                // to remove it and this loop (if its smart enough?).
                perftouchbuffer += (ULONG) *start;
                start += PAGE_SIZE;
            }
        }
    } except (EXCEPTION_EXECUTE_HANDLER) {
        //
        // we might get STATUS_IN_PAGE_ERROR 
        //
        CmKdPrintEx((DPFLTR_CONFIG_ID,DPFLTR_ERROR_LEVEL,"CmpFileWrite has raised :%08lx\n",GetExceptionCode()));
        return FALSE;
    }

    WriteBlock = (PCM_WRITE_BLOCK)ExAllocatePool(NonPagedPool,sizeof(CM_WRITE_BLOCK));
    if( WriteBlock == NULL ) {
        return FALSE;
    }

    for (idx = 0; idx < MAXIMUM_WAIT_OBJECTS; idx++) {
        WriteBlock->EventHandles[idx] = NULL;
#if DBG
        WriteBlock->EventObjects[idx] = NULL;
#endif
    }
    //
    // We'd really like to just call the filesystems and have them do
    // the right thing.  But the filesystem will attempt to lock our
    // entire buffer into memory, and that may fail for large requests.
    // So we split our reads into 64k chunks and call the filesystem for
    // each one.
    //
    ASSERT_PASSIVE_LEVEL();
    arrayCount = 0;
    DataLength = 0;
    // This outer loop is hit more than once if the MAXIMUM_WAIT_OBJECTS limit
    // is hit before the offset array is drained.
    while (arrayCount < offsetArrayCount) {
        WaitBufferCount = 0;

        // This loop fills the wait buffer.
        while ((arrayCount < offsetArrayCount) &&
               (WaitBufferCount < MAXIMUM_WAIT_OBJECTS)) {

            // If data length isn't zero than the wait buffer filled before the
            // buffer in the last offsetArray element was sent to write file.
            if (DataLength == 0) {
                *FileOffset = offsetArray[arrayCount].FileOffset;
                DataBuffer =  offsetArray[arrayCount].DataBuffer;
                DataLength =  offsetArray[arrayCount].DataLength;
                //
                // Detect attempt to read off end of 2gig file
                // (this should be irrelevant)
                //
                if ((0xffffffff - *FileOffset) < DataLength) {
                    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpFileWrite: runoff\n"));
                    status = STATUS_INVALID_PARAMETER_5;
                    goto Error_Exit;
                }
            }
            // else still more to write out of last buffer.

            while ((DataLength > 0) && (WaitBufferCount < MAXIMUM_WAIT_OBJECTS)) {

                //
                // Convert ULONG to Large
                //
                Offset.LowPart = *FileOffset;
                Offset.HighPart = 0L;

                //
                // trim request down if necessary.
                //
                if (DataLength > MAX_FILE_IO) {
                    LengthToWrite = MAX_FILE_IO;
                } else {
                    LengthToWrite = DataLength;
                }

                // Previously created events are reused.
                if (WriteBlock->EventHandles[WaitBufferCount] == NULL) {
                    status = CmpCreateEvent(SynchronizationEvent,
                                            &(WriteBlock->EventHandles[WaitBufferCount]),
                                            &(WriteBlock->EventObjects[WaitBufferCount]));
                    if (!NT_SUCCESS(status)) {
                        // Make sure we don't try to clean this up.
                        WriteBlock->EventHandles[WaitBufferCount] = NULL;
                        goto Error_Exit;
                    }
                    CmpSetHandleProtection(WriteBlock->EventHandles[WaitBufferCount],TRUE);
                }
                
                status = ZwWriteFile(FileHandle,
                                     WriteBlock->EventHandles[WaitBufferCount],
                                     NULL,               // apcroutine
                                     NULL,               // apccontext
                                     &(WriteBlock->IoStatus[WaitBufferCount]),
                                     DataBuffer,
                                     LengthToWrite,
                                     &Offset,
                                     NULL);
                        
                if (!NT_SUCCESS(status)) {
                    goto Error_Exit;
                } 

                WaitBufferCount++;
                
                //
                // adjust offsets
                //
                *FileOffset = Offset.LowPart + LengthToWrite;
                DataLength -= LengthToWrite;
                DataBuffer = (PVOID)((PCHAR)DataBuffer + LengthToWrite);
            } // while (DataLength > 0 && WaitBufferCount < MAXIMUM_WAIT_OBJECTS)
            
            arrayCount++;
            
        } // while (arrayCount < offsetArrayCount && 
          //        WaitBufferCount < MAXIMUM_WAIT_OBJECTS)

        status = KeWaitForMultipleObjects(WaitBufferCount, 
                                          WriteBlock->EventObjects,
                                          WaitAll,
                                          Executive,
                                          KernelMode, 
                                          FALSE, 
                                          NULL,
                                          WriteBlock->WaitBlockArray);
    
        if (!NT_SUCCESS(status))
            goto Error_Exit;
    
        for (idx = 0; idx < WaitBufferCount; idx++) {
            if (!NT_SUCCESS(WriteBlock->IoStatus[idx].Status)) {
                status = WriteBlock->IoStatus[idx].Status;
                ret_val = FALSE;
                goto Done;
            }
        }
        
        // There may still be more to do if the last element held a big buffer
        // and the wait buffer filled before it was all sent to the file.
        if (DataLength > 0) {
            arrayCount--;
        }

    } // while (arrayCount < offsetArrayCount)

    ret_val = TRUE;

    goto Done;
Error_Exit:
    //
    // set debugging info
    //
    CmRegistryIODebug.Action = CmpIoFileWrite;
    CmRegistryIODebug.Handle = FileHandle;
    CmRegistryIODebug.Status = status;
#if DBG
    DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"CmpFileWrite: error exiting %d\n", status);
#endif
    //
    // if WaitBufferCount > 0 then we have successfully issued
    // some I/Os, but not all of them. This is an error, but we
    // cannot return from this routine until all the successfully
    // issued I/Os have completed.
    //
    if (WaitBufferCount > 0) {
        //
        // only if we decided that we want to wait for the write to complete 
        // (log files and hives not using the mapped views technique)
        //
        status = KeWaitForMultipleObjects(WaitBufferCount, 
                                          WriteBlock->EventObjects,
                                          WaitAll,
                                          Executive,
                                          KernelMode, 
                                          FALSE, 
                                          NULL,
                                          WriteBlock->WaitBlockArray);
    }


    ret_val = FALSE;
Done:
    idx = 0;
    // Clean up open event handles and objects.
    while ((idx < MAXIMUM_WAIT_OBJECTS) && (WriteBlock->EventHandles[idx] != NULL)) {
        ASSERT( WriteBlock->EventObjects[idx] );
        ObDereferenceObject(WriteBlock->EventObjects[idx]);
        CmCloseHandle(WriteBlock->EventHandles[idx]);
        idx++;
    }

    if( WriteBlock != NULL ) {
        ExFreePool(WriteBlock);
    }

    return ret_val;
}
Example #14
0
BOOLEAN
CmpFileRead (
    PHHIVE      Hive,
    ULONG       FileType,
    PULONG      FileOffset,
    PVOID       DataBuffer,
    ULONG       DataLength
    )
/*++

Routine Description:

    This routine reads in a buffer from a file.

    It is environment specific.

    NOTE:   We assume the handle is opened for asynchronous access,
            and that we, and not the IO system, are keeping the
            offset pointer.

    NOTE:   Only 32bit offsets are supported, even though the underlying
            IO system on NT supports 64 bit offsets.

Arguments:

    Hive - Hive we are doing I/O for

    FileType - which supporting file to use

    FileOffset - pointer to variable providing 32bit offset on input,
                 and receiving new 32bit offset on output.

    DataBuffer - pointer to buffer

    DataLength - length of buffer

Return Value:

    FALSE if failure
    TRUE if success

--*/
{
    NTSTATUS status;
    LARGE_INTEGER   Offset;
    IO_STATUS_BLOCK IoStatus;
    PCMHIVE CmHive;
    HANDLE  FileHandle;
    ULONG LengthToRead;
    HANDLE eventHandle = NULL;
    PKEVENT eventObject = NULL;

    ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0);
    CmHive = (PCMHIVE)Hive;
    FileHandle = CmHive->FileHandles[FileType];
    if (FileHandle == NULL) {
        return TRUE;
    }

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_IO,"CmpFileRead:\n"));
    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_IO,"\tHandle=%08lx  Offset=%08lx  ", FileHandle, *FileOffset));
    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_IO,"Buffer=%p  Length=%08lx\n", DataBuffer, DataLength));

    //
    // Detect attempt to read off end of 2gig file (this should be irrelevant)
    //
    if ((0xffffffff - *FileOffset) < DataLength) {
        CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpFileRead: runoff\n"));
        return FALSE;
    }

    status = CmpCreateEvent(
        SynchronizationEvent,
        &eventHandle,
        &eventObject);
    if (!NT_SUCCESS(status))
        return FALSE;

    //
    // We'd really like to just call the filesystems and have them do
    // the right thing.  But the filesystem will attempt to lock our
    // entire buffer into memory, and that may fail for large requests.
    // So we split our reads into 64k chunks and call the filesystem for
    // each one.
    //
    ASSERT_PASSIVE_LEVEL();
    while (DataLength > 0) {

        //
        // Convert ULONG to Large
        //
        Offset.LowPart = *FileOffset;
        Offset.HighPart = 0L;

        //
        // trim request down if necessary.
        //
        if (DataLength > MAX_FILE_IO) {
            LengthToRead = MAX_FILE_IO;
        } else {
            LengthToRead = DataLength;
        }

        status = ZwReadFile(
                    FileHandle,
                    eventHandle,
                    NULL,               // apcroutine
                    NULL,               // apccontext
                    &IoStatus,
                    DataBuffer,
                    LengthToRead,
                    &Offset,
                    NULL                // key
                    );

        if (STATUS_PENDING == status) {
            status = KeWaitForSingleObject(eventObject, Executive,
                                           KernelMode, FALSE, NULL);
            ASSERT(STATUS_SUCCESS == status);
            status = IoStatus.Status;
        }

        //
        // adjust offsets
        //
        *FileOffset = Offset.LowPart + LengthToRead;
        DataLength -= LengthToRead;
        DataBuffer = (PVOID)((PCHAR)DataBuffer + LengthToRead);

        if (NT_SUCCESS(status)) {
            ASSERT(IoStatus.Status == status);
            if (IoStatus.Information != LengthToRead) {
                CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpFileRead:\n\t"));
                CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Failure1: status = %08lx  ", status));
                CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"IoInformation = %08lx\n", IoStatus.Information));
                ObDereferenceObject(eventObject);
                ZwClose(eventHandle);
                CmRegistryIODebug.Action = CmpIoFileRead;
                CmRegistryIODebug.Handle = FileHandle;
#if defined(_WIN64)
                CmRegistryIODebug.Status = (ULONG)IoStatus.Information - LengthToRead;
#else
                CmRegistryIODebug.Status = (ULONG)&IoStatus;
#endif
                return FALSE;
            }
        } else {
            //
            // set debugging info
            //
            CmRegistryIODebug.Action = CmpIoFileRead;
            CmRegistryIODebug.Handle = FileHandle;
            CmRegistryIODebug.Status = status;
#if DBG
            DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"CmpFileRead:\tFailure2: status = %08lx  IoStatus = %08lx\n", status, IoStatus.Status);
#endif

            ObDereferenceObject(eventObject);
            ZwClose(eventHandle);
            return FALSE;
        }

    }
    ObDereferenceObject(eventObject);
    ZwClose(eventHandle);
    return TRUE;
}
NTSTATUS
RosKmAdapter::QueryAdapterInfo(
    IN_CONST_PDXGKARG_QUERYADAPTERINFO      pQueryAdapterInfo)
{
    NTSTATUS        Status = STATUS_INVALID_PARAMETER;

    DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "RosKmdQueryAdapterInfo Type=%d\n",
        pQueryAdapterInfo->Type);

    switch (pQueryAdapterInfo->Type)
    {
    case DXGKQAITYPE_UMDRIVERPRIVATE:
    {
        if (pQueryAdapterInfo->OutputDataSize < sizeof(ROSADAPTERINFO))
        {
            Status = STATUS_INVALID_PARAMETER;
            break;
        }
        ROSADAPTERINFO* pRosAdapterInfo = (ROSADAPTERINFO*)pQueryAdapterInfo->pOutputData;

        pRosAdapterInfo->m_version = ROSD_VERSION;
        pRosAdapterInfo->m_wddmVersion = m_WDDMVersion;

        // Software APCI device only claims an interrupt resource
        pRosAdapterInfo->m_isSoftwareDevice = (m_flags.m_isVC4 != 1);

        RtlCopyMemory(
            pRosAdapterInfo->m_deviceId,
            m_deviceId,
            m_deviceIdLength);

        Status = STATUS_SUCCESS;
    }
    break;

    case DXGKQAITYPE_DRIVERCAPS:
    {
        if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_DRIVERCAPS))
        {
            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        DXGK_DRIVERCAPS    *pDriverCaps = (DXGK_DRIVERCAPS *)pQueryAdapterInfo->pOutputData;

        //
        // HighestAcceptableAddress
        //
        pDriverCaps->HighestAcceptableAddress.QuadPart = -1;

        //
        // TODO[bhouse] MaxAllocationListSlotId
        //

        //
        // TODO[bhouse] ApertureSegmentCommitLimit
        //

        //
        // TODO[bhouse] MaxPointerWidth
        //

        //
        // TODO[bhouse] MaxPointerHeight
        //

        //
        // TODO[bhouse] PointerCaps
        //

        //
        // TODO[bhouse] InterruptMessageNumber
        //

        //
        // TODO[bhouse] NumberOfSwizzlingRanges
        //

        //
        // TODO[bhouse] MaxOverlays
        //

        //
        // TODO[bhouse] GammarRampCaps
        //

        //
        // TODO[bhouse] PresentationCaps
        //

        pDriverCaps->PresentationCaps.SupportKernelModeCommandBuffer = FALSE;
        pDriverCaps->PresentationCaps.SupportSoftwareDeviceBitmaps = TRUE;

        //
        // Cap used for DWM off case, screen to screen blt is slow
        //
        pDriverCaps->PresentationCaps.NoScreenToScreenBlt = TRUE;
        pDriverCaps->PresentationCaps.NoOverlapScreenBlt = TRUE;

        //
        // Allow 16Kx16K (2 << (11 + 3)) texture(redirection device bitmap)
        //
        pDriverCaps->PresentationCaps.MaxTextureWidthShift = 3;
        pDriverCaps->PresentationCaps.MaxTextureHeightShift = 3;

        //
        // TODO[bhouse] MaxQueueFlipOnVSync
        //

        //
        // TODO[bhouse] FlipCaps
        //

        //
        // Use SW flip queue for flip with interval of 1 or more
        //
#if 1
        pDriverCaps->FlipCaps.FlipOnVSyncMmIo = 1;
#endif

        //
        // TODO[bhouse] SchedulingCaps
        //

#if 1
        pDriverCaps->SchedulingCaps.MultiEngineAware = 1;
#endif

        //
        // Set scheduling caps to indicate support for cancelling DMA buffer
        //
#if 1
        pDriverCaps->SchedulingCaps.CancelCommandAware = 1;
#endif

        //
        // Set scheduling caps to indicate driver is preemption aware
        //
#if 1
        pDriverCaps->SchedulingCaps.PreemptionAware = 1;
#endif

        //
        // TODO[bhouse] MemoryManagementCaps
        //
#if 1
        pDriverCaps->MemoryManagementCaps.CrossAdapterResource = 1;
#endif

        //
        // TODO[bhouse] GpuEngineTopology
        //

        pDriverCaps->GpuEngineTopology.NbAsymetricProcessingNodes = m_NumNodes;

        //
        // TODO[bhouse] WDDMVersion
        //              Documentation states that we should not set this value if WDDM 1.3
        //
        pDriverCaps->WDDMVersion = m_WDDMVersion;

        //
        // TODO[bhouse] VirtualAddressCaps
        //

        //
        // TODO[bhouse] DmaBufferCaps
        //

        //
        // TODO[bhouse] PreemptionCaps
        //
#if 1
        pDriverCaps->PreemptionCaps.GraphicsPreemptionGranularity = D3DKMDT_GRAPHICS_PREEMPTION_PRIMITIVE_BOUNDARY;
        pDriverCaps->PreemptionCaps.ComputePreemptionGranularity = D3DKMDT_COMPUTE_PREEMPTION_DISPATCH_BOUNDARY;
#endif

        //
        // TODO[bhouse] SupportNonVGA
        //

        //
        // TODO[bhouse] SupportSmoothRotation
        //

        //
        // TODO[bhouse] SupportPerEngineTDR
        //
#if 1
        pDriverCaps->SupportPerEngineTDR = 1;
#endif

        //
        // TODO[bhouse] SupportDirectFlip
        //
#if 1
        pDriverCaps->SupportDirectFlip = 1;
#endif

        //
        // TODO[bhouse] SupportMultiPlaneOverlay
        //

        //
        // Support SupportRuntimePowerManagement
        //
        pDriverCaps->SupportRuntimePowerManagement = 1;

        //
        // TODO[bhouse] SupportSurpriseRemovalInHibernation
        //

        //
        // TODO[bhouse] HybridDiscrete
        //

        //
        // TODO[bhouse] MaxOverlayPlanes
        //


        Status = STATUS_SUCCESS;
    }
    break;

    case DXGKQAITYPE_QUERYSEGMENT3:
    {
        if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_QUERYSEGMENTOUT3))
        {
            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        DXGK_QUERYSEGMENTOUT3   *pSegmentInfo = (DXGK_QUERYSEGMENTOUT3*)pQueryAdapterInfo->pOutputData;

        Status = STATUS_SUCCESS;

        if (!pSegmentInfo[0].pSegmentDescriptor)
        {
            pSegmentInfo->NbSegment = 2;
        }
        else
        {
            DXGK_SEGMENTDESCRIPTOR3 *pSegmentDesc = pSegmentInfo->pSegmentDescriptor;

            //
            // Private data size should be the maximum of UMD and KMD and the same size must
            // be reported in DxgkDdiCreateContext for paging engine
            //
            pSegmentInfo->PagingBufferPrivateDataSize = sizeof(ROSUMDDMAPRIVATEDATA2);

            pSegmentInfo->PagingBufferSegmentId = ROSD_SEGMENT_APERTURE;
            pSegmentInfo->PagingBufferSize = PAGE_SIZE;

            //
            // Fill out aperture segment descriptor
            //
            memset(&pSegmentDesc[0], 0, sizeof(pSegmentDesc[0]));

            pSegmentDesc[0].Flags.Aperture = TRUE;

            //
            // TODO[bhouse] What does marking it CacheCoherent mean?  What are the side effects?
            //              What happens if we don't mark CacheCoherent?
            //
            pSegmentDesc[0].Flags.CacheCoherent = TRUE;

            //
            // TODO[bhouse] BaseAddress should never be used.  Do we need to set this still?
            //

            pSegmentDesc[0].BaseAddress.QuadPart = ROSD_SEGMENT_APERTURE_BASE_ADDRESS;

            //
            // Our fake apperture is not really visible and doesn't need to be.  We
            // still need to lie that it is visible reporting a bad physical address
            // that will never be used.
            //
            // TODO[bhouse] Investigate why we have to lie.
            //

            pSegmentDesc[0].CpuTranslatedAddress.QuadPart = 0xFFFFFFFE00000000;
            pSegmentDesc[0].Flags.CpuVisible = TRUE;

            pSegmentDesc[0].Size = kApertureSegmentSize;
            pSegmentDesc[0].CommitLimit = kApertureSegmentSize;

            //
            // Setup local video memory segment
            //

            memset(&pSegmentDesc[1], 0, sizeof(pSegmentDesc[1]));

            pSegmentDesc[1].BaseAddress.QuadPart = 0LL; // Gpu base physical address
            pSegmentDesc[1].Flags.CpuVisible = true;
            pSegmentDesc[1].Flags.CacheCoherent = true;
            pSegmentDesc[1].CpuTranslatedAddress = RosKmdGlobal::s_videoMemoryPhysicalAddress; // cpu base physical address
            pSegmentDesc[1].Size = RosKmdGlobal::s_videoMemorySize;

        }
    }
    break;

    case DXGKQAITYPE_NUMPOWERCOMPONENTS:
    {
        if (pQueryAdapterInfo->OutputDataSize != sizeof(UINT))
        {
            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        // Support only one 3D engine(s).
        //
        *(reinterpret_cast<UINT*>(pQueryAdapterInfo->pOutputData)) = GetNumPowerComponents();

        Status = STATUS_SUCCESS;
    }
    break;

    case DXGKQAITYPE_POWERCOMPONENTINFO:
    {
        if (pQueryAdapterInfo->InputDataSize != sizeof(UINT) ||
            pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_POWER_RUNTIME_COMPONENT))
        {
            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        ULONG ComponentIndex = *(reinterpret_cast<UINT*>(pQueryAdapterInfo->pInputData));
        DXGK_POWER_RUNTIME_COMPONENT* pPowerComponent = reinterpret_cast<DXGK_POWER_RUNTIME_COMPONENT*>(pQueryAdapterInfo->pOutputData);

        Status = GetPowerComponentInfo(ComponentIndex, pPowerComponent);
    }
    break;

    case DXGKQAITYPE_HISTORYBUFFERPRECISION:
    {
        UINT NumStructures = pQueryAdapterInfo->OutputDataSize / sizeof(DXGKARG_HISTORYBUFFERPRECISION);

        for (UINT i = 0; i < NumStructures; i++)
        {
            DXGKARG_HISTORYBUFFERPRECISION *pHistoryBufferPrecision = ((DXGKARG_HISTORYBUFFERPRECISION *)pQueryAdapterInfo->pOutputData) + i;

            pHistoryBufferPrecision->PrecisionBits = 64;
        }

        Status = STATUS_SUCCESS;
    }
    break;

    default:
        // NT_ASSERT(FALSE);
        break;
    }

    return Status;
}
NTSTATUS
__stdcall
RosKmContext::DdiRender(
    IN_CONST_HANDLE         hContext,
    INOUT_PDXGKARG_RENDER   pRender)
{
    DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "RosKmdRender hAdapter=%lx\n", hContext);

    RosKmContext  *pRosKmContext = (RosKmContext *)hContext;
    pRosKmContext;

    pRender->MultipassOffset;
    pRender->DmaBufferSegmentId;
    pRender->DmaBufferPhysicalAddress;
    pRender->pDmaBufferPrivateData;
    pRender->DmaBufferPrivateDataSize;

    // Copy command buffer
    NT_ASSERT(pRender->DmaSize >= pRender->CommandLength);

    __try {
        memcpy(pRender->pDmaBuffer, pRender->pCommand, pRender->CommandLength);
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        return STATUS_INVALID_PARAMETER;
    }

    // Check to command buffer header
    GpuCommand *    pCmdBufHeader = (GpuCommand *)pRender->pDmaBuffer;
    if (pCmdBufHeader->m_commandId != Header)
    {
        return STATUS_ILLEGAL_INSTRUCTION;
    }

    // Copy path list
    NT_ASSERT(pRender->PatchLocationListOutSize >= pRender->PatchLocationListInSize);

    D3DDDI_PATCHLOCATIONLIST * pPatchLocationList = pRender->pPatchLocationListOut;

    __try {
        for (UINT i = 0; i < pRender->PatchLocationListInSize; i++)
        {
            pPatchLocationList[i] = pRender->pPatchLocationListIn[i];
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        return STATUS_INVALID_PARAMETER;
    }

    // Must update pPatchLocationListOut to reflect what space was used
    pRender->pPatchLocationListOut += pRender->PatchLocationListInSize;

    // Perform pre-patch
    PBYTE   pDmaBuf = (BYTE *)pCmdBufHeader;
    for (UINT i = 0; i < pRender->PatchLocationListInSize; i++)
    {
        auto patch = &pPatchLocationList[i];
        NT_ASSERT(patch->AllocationIndex < pRender->AllocationListSize);
        auto allocation = &pRender->pAllocationList[patch->AllocationIndex];

        if (allocation->SegmentId != 0)
        {
            RosKmdDeviceAllocation * pRosKmdDeviceAllocation = (RosKmdDeviceAllocation *)allocation->hDeviceSpecificAllocation;

            DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Pre-patch RosKmdDeviceAllocation %lx at %lx\n", pRosKmdDeviceAllocation, allocation->PhysicalAddress);
            DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Pre-patch buffer offset %lx allocation offset %lx\n", patch->PatchOffset, patch->AllocationOffset);

            // Patch in dma buffer
            NT_ASSERT(allocation->SegmentId == ROSD_SEGMENT_VIDEO_MEMORY);
            if (pCmdBufHeader->m_commandBufferHeader.m_swCommandBuffer)
            {
                *((PHYSICAL_ADDRESS *)(pDmaBuf + patch->PatchOffset)) = allocation->PhysicalAddress;
            }
            else
            {
                // Patch HW command buffer
            }
        }

    }

    // Record DMA buffer information
    ROSDMABUFINFO * pDmaBufInfo = (ROSDMABUFINFO *)pRender->pDmaBufferPrivateData;

    pDmaBufInfo->m_DmaBufState.m_Value = 0;
    pDmaBufInfo->m_DmaBufState.m_Render = 1;
    pDmaBufInfo->m_DmaBufState.m_bSwCommandBuffer = pCmdBufHeader->m_commandBufferHeader.m_swCommandBuffer;

    pDmaBufInfo->m_pDmaBuffer = (PBYTE)pRender->pDmaBuffer;
    pDmaBufInfo->m_DmaBufferSize = pRender->DmaSize;

    // Must update pDmaBuffer to reflect what space we used
    pRender->pDmaBuffer = (char *)pRender->pDmaBuffer + pRender->CommandLength;

    return STATUS_SUCCESS;
}
Example #17
0
File: Pnp.c Project: uri247/pmgmt
NTSTATUS
QueryCapability(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp
    )
{
	PIO_STACK_LOCATION pStk;
	PDEVICE_EXTENSION pCtx;
	NTSTATUS Status;
	KEVENT event;
	ULONG IdxPwrState;

	DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Query Device Capability....\r\n");
	DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Ready to pass IRP down\r\n");
	
	pStk = IoGetCurrentIrpStackLocation(Irp);
	pCtx = DeviceObject->DeviceExtension;

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	IoCopyCurrentIrpStackLocationToNext(Irp);

	IoSetCompletionRoutine(
		Irp,
		(PIO_COMPLETION_ROUTINE)CompletionQueryCapability,
		(PVOID)&event,//pCtx,
		TRUE,
		TRUE,
		TRUE);

	Status = IoCallDriver(
				pCtx->NextDeviceObject,
				Irp);

	KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

	if (NT_SUCCESS(Irp->IoStatus.Status)) {
		pStk = IoGetCurrentIrpStackLocation(Irp);
		pCtx = (DEVICE_EXTENSION*)DeviceObject->DeviceExtension;
		pCtx->pdc = *pStk->Parameters.DeviceCapabilities.Capabilities;
		Global_PowerInfo_Ptr->SupportQueryCapability = TRUE;
		Global_PowerInfo_Ptr->DeviceD1 = pCtx->pdc.DeviceD1;
		Global_PowerInfo_Ptr->DeviceD2 = pCtx->pdc.DeviceD1;
		Global_PowerInfo_Ptr->WakeFromD0 = pCtx->pdc.WakeFromD0;
		Global_PowerInfo_Ptr->WakeFromD1 = pCtx->pdc.WakeFromD1;
		Global_PowerInfo_Ptr->WakeFromD2 = pCtx->pdc.WakeFromD2;
		Global_PowerInfo_Ptr->WakeFromD3 = pCtx->pdc.WakeFromD3;
		Global_PowerInfo_Ptr->DeviceWake = pCtx->pdc.DeviceWake;
		Global_PowerInfo_Ptr->SystemWake = pCtx->pdc.SystemWake;
		for (IdxPwrState = 0; 
			IdxPwrState < PowerSystemMaximum;
			IdxPwrState++)
		{
			Global_PowerInfo_Ptr->DeviceState[IdxPwrState] = 
				pCtx->pdc.DeviceState[IdxPwrState];
		}
	} else {
		DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Failed to handle IRP_MN_QUERY_CAPABILITIES");
	}
	return Irp->IoStatus.Status;
}
Example #18
0
File: PoFx.c Project: uri247/kmdf
///////////////////////////////////////////////////////////////////////////////
// Initialization of component level power management.
///////////////////////////////////////////////////////////////////////////////
VOID
SmplPoFxSingleComponentInitialize(
    _In_ WDFDEVICE Device
)
{
    WDF_POWER_FRAMEWORK_SETTINGS Settings;
    PO_FX_COMPONENT Component;
    PO_FX_COMPONENT_IDLE_STATE IdleStates[FSTATE_COUNT];
    NTSTATUS Status;

    //
    // Initialization
    //
    RtlZeroMemory(&Component, sizeof(Component));
    RtlZeroMemory(&IdleStates, sizeof(IdleStates));

    //
    // The transition latency and residency requirement values used here are for
    // illustration purposes only. The driver should use values that are
    // appropriate for its device.
    //

    //
    // F0
    //
    IdleStates[0].TransitionLatency = 0;
    IdleStates[0].ResidencyRequirement = 0;
    IdleStates[0].NominalPower = 0;

    //
    // F1
    //
    IdleStates[1].TransitionLatency = WDF_ABS_TIMEOUT_IN_MS(200);
    IdleStates[1].ResidencyRequirement = WDF_ABS_TIMEOUT_IN_SEC(3);
    IdleStates[1].NominalPower = 0;

    //
    // F2
    //
    IdleStates[2].TransitionLatency = WDF_ABS_TIMEOUT_IN_MS(400);
    IdleStates[2].ResidencyRequirement = WDF_ABS_TIMEOUT_IN_SEC(6);
    IdleStates[2].NominalPower = 0;

    //
    // F3
    //
    IdleStates[3].TransitionLatency = WDF_ABS_TIMEOUT_IN_MS(DEEPEST_FSTATE_LATENCY_IN_MS);
    IdleStates[3].ResidencyRequirement = WDF_ABS_TIMEOUT_IN_SEC(DEEPEST_FSTATE_RESIDENCY_IN_SEC);
    IdleStates[3].NominalPower = 0;

    //
    // Component 0 (the only component)
    //
    Component.IdleStateCount = FSTATE_COUNT;
    Component.IdleStates = IdleStates;

    WDF_POWER_FRAMEWORK_SETTINGS_INIT(&Settings);

    Settings.EvtDeviceWdmPostPoFxRegisterDevice = SmplDeviceEvtWdmPostPoFxRegisterDevice;

    Settings.Component = &Component;
    Settings.ComponentActiveConditionCallback = SmplPoFxComponentActiveConditionCallback;
    Settings.ComponentIdleConditionCallback =   SmplPoFxComponentIdleConditionCallback;
    Settings.ComponentIdleStateCallback = SmplPoFxComponentIdleStateCallback;
    Settings.PoFxDeviceContext = (PVOID) Device;



    Status = WdfDeviceWdmAssignPowerFrameworkSettings(Device, &Settings);
    if (FALSE == NT_SUCCESS(Status))
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"WdfDeviceWdmAssignPowerFrameworkSettings failed! 0x%x\n", Status);
    }

} // end SmplPoFxSingleComponentInitialize
_IRQL_requires_same_
VOID ClassifyPendAuthorization(_In_ const FWPS_INCOMING_VALUES* pClassifyValues,
                               _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata,
                               _Inout_opt_ VOID* pNetBufferList,
                               _In_ const FWPS_FILTER* pFilter,
                               _In_ UINT64 flowContext,
                               _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> ClassifyPendAuthorization()\n");

#endif /// DBG
   
   NT_ASSERT(pClassifyValues);
   NT_ASSERT(pMetadata);
   NT_ASSERT(pFilter);
   NT_ASSERT(pClassifyOut);
   NT_ASSERT(pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 ||
             pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6);
   NT_ASSERT(pFilter->providerContext);
   NT_ASSERT(pFilter->providerContext->type == FWPM_GENERAL_CONTEXT);
   NT_ASSERT(pFilter->providerContext->dataBuffer);
   NT_ASSERT(pFilter->providerContext->dataBuffer->size == sizeof(PC_PEND_AUTHORIZATION_DATA));
   NT_ASSERT(pFilter->providerContext->dataBuffer->data);

   NTSTATUS                    status                 = STATUS_SUCCESS;
   PC_PEND_AUTHORIZATION_DATA* pPendAuthorizationData = (PC_PEND_AUTHORIZATION_DATA*)pFilter->providerContext->dataBuffer->data;

   /// AUTH_CONNECT's completeOperation will trigger a Reauthorization
   if(KrnlHlprFwpsIncomingValueConditionFlagsAreSet(pClassifyValues,
                                                    FWP_CONDITION_FLAG_IS_REAUTHORIZE))
   {
      if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
         pClassifyOut->actionType = pPendAuthorizationData->finalAction;
   }
   else
   {
      BOOLEAN actionSet = FALSE;

      if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
      {
         INJECTION_DATA* pInjectionData = 0;
         PEND_DATA*      pPendData      = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy

         status = KrnlHlprInjectionDataCreate(&pInjectionData,
                                              pClassifyValues,
                                              pMetadata,
                                              (NET_BUFFER_LIST*)pNetBufferList);
         HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

         /// AUTH_RECV_ACCEPT's injection will be indicative of PERMIT
         if(pInjectionData->injectionState == FWPS_PACKET_INJECTED_BY_SELF)
         {
            pClassifyOut->actionType = pPendAuthorizationData->finalAction;

            actionSet = TRUE;
         }
         else
         {
#pragma warning(push)
#pragma warning(disable: 6014) /// pInjectionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy

            status = KrnlHlprPendDataCreate(&pPendData,
                                            pMetadata,
                                            (NET_BUFFER_LIST*)pNetBufferList,
                                            pFilter);
            HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

            status = TriggerPendAuthorizationOutOfBand(pClassifyValues,
                                                       pMetadata,
                                                       pNetBufferList,
                                                       0,
                                                       pFilter,
                                                       flowContext,
                                                       pClassifyOut,
                                                       pInjectionData,
                                                       pPendData,
                                                       pPendAuthorizationData);
         }

         HLPR_BAIL_LABEL:

         if(status != STATUS_SUCCESS)
         {
            DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                       DPFLTR_ERROR_LEVEL,
                       " !!!! ClassifyPendAuthorization() [status: %#x]\n",
                       status);

            if(pInjectionData)
               KrnlHlprInjectionDataDestroy(&pInjectionData);

            if(pPendData)
               KrnlHlprPendDataDestroy(&pPendData);
         }

         if(!actionSet)
         {
            pClassifyOut->actionType  = FWP_ACTION_BLOCK;
            pClassifyOut->flags      |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
         }
      }
   }

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- ClassifyPendAuthorization()\n");

#endif /// DBG
   
   return;
}
Example #20
0
NTSTATUS
ReinjectPendedPacket(
	IN PENDED_PACKET *packet,
	IN FLOW_DATA *flowData)
{
	NTSTATUS status;
	UINT32 flags;
	NET_BUFFER_LIST* netBufferList = NULL;
	FLOW_DATA *flowCtx;
	ULONG dataLength;

	if(packet->dataLength == 0 || packet->data == NULL)
	{
		return STATUS_UNSUCCESSFUL;
	}

	packet->mdl = IoAllocateMdl(
		packet->data,
		packet->dataLength,
		FALSE,
		FALSE,
		NULL);
	
	if (packet->mdl == NULL)
	{
		status = STATUS_NO_MEMORY;
		goto Exit;
	}

	MmBuildMdlForNonPagedPool(packet->mdl);
	
	status = FwpsAllocateNetBufferAndNetBufferList(
						gNetBufferListPool,
						0,
						0,
						packet->mdl,
						0,
						packet->dataLength,
						&netBufferList);

	if(!NT_SUCCESS(status))
	{
		goto Exit;
	}

	flags = packet->flags;
	dataLength = packet->dataLength;
	flowCtx = packet->flowContext;

#ifdef DEBUG
	debugPacket(packet);
	DbgPrintEx(
		DPFLTR_IHVNETWORK_ID,
		DPFLTR_ERROR_LEVEL,
		"\n localCtr=%d, remoteCtr=%d\n", flowCtx->localCounter, flowCtx->remoteCounter);
#endif

	// Keep correct sequence numbers
	// (Assume every reinjection is successful, otherwise synchronous injection is
	// needed for consistent sequence numbers implementation)
	if(flags & FWPS_STREAM_FLAG_SEND)
	{
		flowCtx->localCounter += dataLength;
	}
	else if(flags & FWPS_STREAM_FLAG_RECEIVE)
	{
		flowCtx->remoteCounter += dataLength;
	}
	else
	{
#ifdef DEBUG
		DbgBreakPoint();
#endif
	}

	status = FwpsStreamInjectAsync(
		gInjectionHandle,
		NULL,
		0,
		flowData->flowHandle,
		gStreamCalloutIdV4,
		FWPS_LAYER_STREAM_V4,
		flags, 
		netBufferList,
		packet->dataLength,
		StreamInjectCompletionFn,
		packet);

	if (!NT_SUCCESS(status))
	{
		goto Exit;
	}

	// Ownership transferred
	netBufferList = NULL;
	packet = NULL;

	

Exit:

	if (netBufferList != NULL)
	{
		FwpsFreeNetBufferList(netBufferList);
	}

	if (packet != NULL)
	{
		FreePendedPacket(packet);
	}

	return status;
}
Example #21
0
///////////////////////////////////////////////////////////////////////////////
///
/// This function handles 'control' irp.
///
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
TdDeviceControl(
IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp
)
{
	PIO_STACK_LOCATION IrpStack;
	ULONG Ioctl;
	NTSTATUS Status;

	UNREFERENCED_PARAMETER(DeviceObject);


	Status = STATUS_SUCCESS;

	IrpStack = IoGetCurrentIrpStackLocation(Irp);
	Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode;

	DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TdDeviceControl: entering - ioctl code 0x%x\n", Ioctl);

	// Sanity check: Check the size of the request
	if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COMM_REQUEST)) {
		// Wrong size
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "TdDeviceControl: Wrong size request\n");
		Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
		Irp->IoStatus.Information = sizeof(COMM_REQUEST);
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_BUFFER_OVERFLOW;
	}

	switch (Ioctl)
	{
	case QD_IOCTL_GET_NEW_PROCESSES:
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TdDeviceControl: recieved QD_IOCTL_GET_NEW_PROCESSES\n");

		// Process it
		Status = ProcessIoctl_GetNewProcesses(Irp);

		//
		// Complete the irp and return.
		//
		Irp->IoStatus.Status = Status;
		if (STATUS_PENDING != Status) {
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		}

		break;
	case QD_IOCTL_CONTROLLER_PROCESS_DECISION:
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TdDeviceControl: recieved QD_IOCTL_CONTROLLER_PROCESS_DECISION\n");

		// Process it
		Status = ProcessIoctl_ControllerProcessDecision(Irp);

		//
		// Complete the irp and return.
		//
		Irp->IoStatus.Status = Status;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);

		break;
	default:
		//
		// Invalid request operation
		//
		DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "TdDeviceControl: unrecognized ioctl code 0x%x\n", Ioctl);

		Status = STATUS_INVALID_DEVICE_REQUEST;
		Irp->IoStatus.Status = Status;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	}

	DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TdDeviceControl leaving - status 0x%x\n", Status);
	return Status;
}
Example #22
0
NTSTATUS Mouse_Hook(IN PDRIVER_OBJECT driverObject)
{
	ULONG i;
	int found = 1;
	NTSTATUS status = STATUS_SUCCESS;
	PIO_STACK_LOCATION stack;
	UNICODE_STRING uniMouseDeviceName;
	PFILE_OBJECT mouseFileObject;
	PDEVICE_OBJECT MouseDeviceObject;
	ULONG counter;
	HANDLE hDir;
	OBJECT_ATTRIBUTES oa;
	UNICODE_STRING uniOa;
	PVOID pBuffer;
	PVOID pContext;
	ULONG RetLen;
	PDIRECTORY_BASIC_INFORMATION pDirBasicInfo;
	UNICODE_STRING uniMouseDrv;
	char* mouseclsNum;
	char arMouseCls[0x10];
	WCHAR tmpNameBuffer[512];

	DbgPrint("Running Mouse_Create.");


	RtlInitUnicodeString(&uniOa, L"\\Device");

	InitializeObjectAttributes(	&oa,&uniOa,	OBJ_CASE_INSENSITIVE,NULL,NULL);

	status = ZwOpenDirectoryObject(	&hDir,DIRECTORY_ALL_ACCESS,&oa);
	if(!NT_SUCCESS(status)) return status;

	pBuffer = ExAllocatePool(PagedPool, ALLOC_SIZE);
	pContext = ExAllocatePool(PagedPool, ALLOC_SIZE);
// 		pBuffer = ExAllocatePoolWithTag(PagedPool, ALLOC_SIZE, Tag);
// 		pContext = ExAllocatePoolWithTag(PagedPool, ALLOC_SIZE, Tag);
	memset(pBuffer, 0, ALLOC_SIZE);
	memset(pContext, 0, ALLOC_SIZE);
	memset(arMouseCls, 0, 0x10);
	counter = 0;
	g_Mouseclsnum = 0;

	while(TRUE)	{
		status = ZwQueryDirectoryObject(hDir,pBuffer,ALLOC_SIZE,TRUE,FALSE,pContext,&RetLen);
		if(!NT_SUCCESS(status)) break;

		pDirBasicInfo =	(PDIRECTORY_BASIC_INFORMATION)pBuffer;
		pDirBasicInfo->ObjectName.Length -= 2;

		RtlInitUnicodeString(&uniMouseDrv, L"PointerClass");

		if(RtlCompareUnicodeString(	&pDirBasicInfo->ObjectName, &uniMouseDrv,FALSE) == 0){
			mouId = (ULONG)(*(char *)(pDirBasicInfo->ObjectName.Buffer+pDirBasicInfo->ObjectName.Length));
			mouId -= 0x30;
			pDirBasicInfo->ObjectName.Length += 2;
			RtlInitUnicodeString(&uniMouseDeviceName, pDirBasicInfo->ObjectName.Buffer);

			found = 1;
			break;
		}
		pDirBasicInfo->ObjectName.Length += 2;
	}
	ExFreePool(pBuffer);
	ExFreePool(pContext);
	ZwClose(hDir);

	if( found == 0 ) return status;
	DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Mouse_Hook ----> mouId[%d].\n", mouId);
				
	swprintf(tmpNameBuffer, L"\\Device\\%s", uniMouseDeviceName.Buffer);
	RtlInitUnicodeString(&uniMouseDeviceName, tmpNameBuffer);

	status = My_IoGetDeviceObjectPointer(&uniMouseDeviceName, FILE_ALL_ACCESS, &mouseFileObject,&MouseDeviceObject);

	if(NT_SUCCESS(status)) {
		g_MouseDeviceObject = MouseDeviceObject;
		ObDereferenceObject(mouseFileObject);
		g_OldReadFunction = g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ];
		g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ] = Mouse_HookProc;
		g_OldInternalDeviceFunction = g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL];
		g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = Mouse_IO_InternalIoctl;

		DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Mouse_Create ----> Mouse_HookProc success.\n");
	}
	return status;
}
Example #23
0
///////////////////////////////////////////////////////////////////////////////
// Private local helper function that parses the translated resource list 
// and extracts the data needed for the port address.
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
SmplDeviceHwResourcesGet(
    IN WDFDEVICE Device,
    IN WDFCMRESLIST ResourcesTranslated
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG index = 0;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR  pCMResourceDescPartial;
    PDEVICE_CONTEXT pSmplDeviceContext = NULL;

    pSmplDeviceContext = DeviceGetContext(Device);

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplDeviceHwResourcesGet >>\n");

    if (NULL != pSmplDeviceContext)
    {
        for (index = 0; index < WdfCmResourceListGetCount(ResourcesTranslated); index++)
        {
            pCMResourceDescPartial = WdfCmResourceListGetDescriptor(ResourcesTranslated, index);
            
            if (NULL == pCMResourceDescPartial)
            {
                DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"pCMResourceDescPartial is NULL!!!\n");
                return STATUS_DEVICE_CONFIGURATION_ERROR;
            }

            switch (pCMResourceDescPartial->Type) 
            {
                case CmResourceTypeMemory:
                    //
                    // Handle memory resources here.
                    //
                    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceTypeMemory Desc\n");
                    break;

                case CmResourceTypePort:
                    //
                    // Handle port resources here.
                    //
                    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceTypePort 0x%x %d\n", pCMResourceDescPartial->u.Port.Start.LowPart, pCMResourceDescPartial->u.Port.Length);
                    pSmplDeviceContext->pPortAddress = (PUCHAR) pCMResourceDescPartial->u.Port.Start.LowPart;
                    pSmplDeviceContext->PortAddressLength = pCMResourceDescPartial->u.Port.Length;
                    break;

                case CmResourceTypeInterrupt:
                    //
                    // Handle interrupt resources here.
                    //
                    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceTypeInterrupt\n");

                    break;
                default:
                    //
                    // Ignore all other descriptors.
                    //
                    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"CmResourceType unknown\n");
                    break;
            } // end switch
        } // end for loop
    } // end if

    return Status;

} // end SmplDeviceHwResourcesGet
_Use_decl_annotations_
VOID
TreeSampleProcessOtherDeviceIo(
    WDFDEVICE MasterDevice,
    WDFREQUEST Request
    )

/*++

    Routine Description:

        This routine is called when an unrecognized IO request is made to the
        device. This can be used to process private calls directly to the
        secure device.

    Arguments:

        MasterDevice - Supplies a handle to the master device object.

        DeviceContext - Supplies a pointer to the context.

        Request - Supplies a pointer to the WDF request object.

    Return Value:

        NTSTATUS code.

--*/

{

    PWCHAR Buffer;
    size_t BufferSize;
    ULONG BytesWritten;
    WDF_REQUEST_PARAMETERS Parameters;
    NTSTATUS Status;

    PAGED_CODE();

    UNREFERENCED_PARAMETER(MasterDevice);

    WDF_REQUEST_PARAMETERS_INIT(&Parameters);
    WdfRequestGetParameters(Request, &Parameters);
    BytesWritten = 0;
    switch (Parameters.Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_SAMPLE_DBGPRINT:
        Status = WdfRequestRetrieveInputBuffer(Request,
                                               0,
                                               (PVOID*)&Buffer,
                                               &BufferSize);

        if (!NT_SUCCESS(Status)) {
            goto TreeSampleProcessOtherDeviceIoEnd;
        }

        //
        // Must be NULL-terminated
        //
        if (Buffer[BufferSize / sizeof(WCHAR) - 1] != L'\0') {
            Status = STATUS_INVALID_PARAMETER;
            goto TreeSampleProcessOtherDeviceIoEnd;
        }

        DbgPrintEx(DPFLTR_DEFAULT_ID,
                   DPFLTR_ERROR_LEVEL,
                   "[TrEEMiniportSample] %ws\n",
                   (PWSTR)Buffer);

        break;

    default:
        Status = STATUS_INVALID_DEVICE_REQUEST;
    }

TreeSampleProcessOtherDeviceIoEnd:
    WdfRequestCompleteWithInformation(Request, Status, BytesWritten);
}
NTSTATUS KrnlHlprClassifyDataCreateLocalCopy(_Outptr_ CLASSIFY_DATA** ppClassifyData,
                                             _In_ const FWPS_INCOMING_VALUES* pClassifyValues,
                                             _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata,
                                             _In_opt_ VOID* pPacket,
                                             _In_opt_ const VOID* pClassifyContext,
                                             _In_ const FWPS_FILTER* pFilter,
                                             _In_ const UINT64 flowContext,
                                             _In_ FWPS_CLASSIFY_OUT* pClassifyOut)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprClassifyDataCreateLocalCopy()\n");

#endif /// DBG
   
   NT_ASSERT(ppClassifyData);
   NT_ASSERT(pClassifyValues);
   NT_ASSERT(pMetadata);
   NT_ASSERT(pFilter);
   NT_ASSERT(pClassifyOut);

   NTSTATUS status = STATUS_SUCCESS;

   HLPR_NEW(*ppClassifyData,
            CLASSIFY_DATA,
            WFPSAMPLER_SYSLIB_TAG);
   HLPR_BAIL_ON_ALLOC_FAILURE(*ppClassifyData,
                              status);

   status = KrnlHlprClassifyDataAcquireLocalCopy(*ppClassifyData,
                                                 pClassifyValues,
                                                 pMetadata,
                                                 pPacket,
                                                 pClassifyContext,
                                                 pFilter,
                                                 flowContext,
                                                 pClassifyOut);

   HLPR_BAIL_LABEL:

#pragma warning(push)
#pragma warning(disable: 6001) /// *ppClassifyData initialized with call to HLPR_NEW & KrnlHlprClassifyDataAcquireLocalCopy 

   if(status != STATUS_SUCCESS &&
      *ppClassifyData)
      KrnlHlprClassifyDataDestroyLocalCopy(ppClassifyData);

#pragma warning(pop)

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprClassifyDataCreateLocalCopy() [status: %#x]\n",
              status);

#endif /// DBG

   return status;
}
void
RosKmAdapter::PatchDmaBuffer(
    ROSDMABUFINFO*                  pDmaBufInfo,
    CONST DXGK_ALLOCATIONLIST*      pAllocationList,
    UINT                            allocationListSize,
    CONST D3DDDI_PATCHLOCATIONLIST* pPatchLocationList,
    UINT                            patchAllocationList)
{
    PBYTE       pDmaBuf = (PBYTE)pDmaBufInfo->m_pDmaBuffer;

    for (UINT i = 0; i < patchAllocationList; i++)
    {
        auto patch = &pPatchLocationList[i];

        allocationListSize;
        NT_ASSERT(patch->AllocationIndex < allocationListSize);

        auto allocation = &pAllocationList[patch->AllocationIndex];

        RosKmdDeviceAllocation * pRosKmdDeviceAllocation = (RosKmdDeviceAllocation *)allocation->hDeviceSpecificAllocation;

        if (allocation->SegmentId != 0)
        {
            DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Patch RosKmdDeviceAllocation %lx at %lx\n", pRosKmdDeviceAllocation, allocation->PhysicalAddress);
            DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Patch buffer offset %lx allocation offset %lx\n", patch->PatchOffset, patch->AllocationOffset);

            // Patch in dma buffer
            NT_ASSERT(allocation->SegmentId == ROSD_SEGMENT_VIDEO_MEMORY);
            if (pDmaBufInfo->m_DmaBufState.m_bSwCommandBuffer)
            {
                PHYSICAL_ADDRESS    allocAddress;

                allocAddress.QuadPart = allocation->PhysicalAddress.QuadPart + (LONGLONG)patch->AllocationOffset;
                *((PHYSICAL_ADDRESS *)(pDmaBuf + patch->PatchOffset)) = allocAddress;
            }
            else
            {
                // Patch HW command buffer
#if VC4
                UINT    physicalAddress =
                    RosKmdGlobal::s_videoMemoryPhysicalAddress.LowPart +
                    allocation->PhysicalAddress.LowPart +
                    patch->AllocationOffset;

                switch (patch->SlotId)
                {
                case VC4_SLOT_RT_BINNING_CONFIG:
                    pDmaBufInfo->m_RenderTargetPhysicalAddress = physicalAddress;
                    break;
                case VC4_SLOT_TILE_ALLOCATION_MEMORY:
                    *((UINT *)(pDmaBuf + patch->PatchOffset)) = m_tileAllocationMemoryPhysicalAddress + m_busAddressOffset;
                    break;
                case VC4_SLOT_TILE_STATE_DATA_ARRAY:
                    *((UINT *)(pDmaBuf + patch->PatchOffset)) = m_tileStateDataArrayPhysicalAddress + m_busAddressOffset;
                    break;
                case VC4_SLOT_NV_SHADER_STATE:
                case VC4_SLOT_BRANCH:
                case VC4_SLOT_GL_SHADER_STATE:
                case VC4_SLOT_FS_UNIFORM_ADDRESS:
                case VC4_SLOT_VS_UNIFORM_ADDRESS:
                case VC4_SLOT_CS_UNIFORM_ADDRESS:
                    // When PrePatch happens in DdiRender, DMA buffer physical
                    // address is not available, so DMA buffer self-reference
                    // patches are handled in SubmitCommand
                    break;
                default:
                    *((UINT *)(pDmaBuf + patch->PatchOffset)) = physicalAddress + m_busAddressOffset;
                }
#endif
            }
        }
    }
}
NTSTATUS PerformPendAuthorization(_Inout_ CLASSIFY_DATA** ppClassifyData,
                                  _Inout_ PEND_DATA** ppPendData,
                                  _Inout_ INJECTION_DATA** ppInjectionData)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> PerformPendAuthorization()\n");

#endif /// DBG
   
   NT_ASSERT(ppClassifyData);
   NT_ASSERT(ppPendData);
   NT_ASSERT(ppInjectionData);
   NT_ASSERT(*ppClassifyData);
   NT_ASSERT(*ppPendData);

   NTSTATUS         status      = STATUS_SUCCESS;
   NET_BUFFER_LIST* pNBL        = (*ppPendData)->pNBL;
   UINT32           finalAction = (*ppPendData)->pPendAuthorizationData->finalAction;
   UINT32           delay       = (*ppPendData)->pPendAuthorizationData->delay;
   BOOLEAN          reInjected  = FALSE;

   if(delay &&
      KeGetCurrentIrql() < DISPATCH_LEVEL)
      KrnlHlprWorkItemSleep(delay);

#pragma warning(push)
#pragma warning(disable: 6001) /// *ppPendData initialized prior to call to this function

   /// Completes the Pend
   KrnlHlprPendDataDestroy(ppPendData);

#pragma warning(pop)

   if(pNBL &&
      finalAction == FWP_ACTION_PERMIT)
   {
      status = PrvCloneAuthorizedNBLAndInject(ppClassifyData,
                                              ppInjectionData);
      if(status != STATUS_SUCCESS)
      {
         DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                    DPFLTR_ERROR_LEVEL,
                    " !!!! PerformPendAuthorization : PrvCloneAuthorizedNBLAndInject() [status: %#x]\n",
                    status);
      }
      else
         reInjected = TRUE;
   }

#pragma warning(push)
#pragma warning(disable: 6001) /// *ppClassifyData initialized prior to call to this function

   if(!reInjected)
      KrnlHlprClassifyDataDestroyLocalCopy(ppClassifyData);

#pragma warning(pop)

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- PerformPendAuthorization() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
};
NTSTATUS
RosKmAdapter::BuildPagingBuffer(
    IN_PDXGKARG_BUILDPAGINGBUFFER   pArgs)
{
    NTSTATUS    Status = STATUS_SUCCESS;
    PBYTE       pDmaBufStart = (PBYTE)pArgs->pDmaBuffer;
    PBYTE       pDmaBufPos = (PBYTE)pArgs->pDmaBuffer;

    //
    // hAllocation is NULL for operation on DMA buffer and pages mapped into aperture
    //

    //
    // If there is insufficient space left in DMA buffer, we should return
    // STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER.
    //

    switch (pArgs->Operation)
    {
    case DXGK_OPERATION_MAP_APERTURE_SEGMENT:
    {
        if (pArgs->MapApertureSegment.SegmentId == kApertureSegmentId)
        {
            size_t pageIndex = pArgs->MapApertureSegment.OffsetInPages;
            size_t pageCount = pArgs->MapApertureSegment.NumberOfPages;

            NT_ASSERT(pageIndex + pageCount <= kApertureSegmentPageCount);

            size_t mdlPageOffset = pArgs->MapApertureSegment.MdlOffset;

            PMDL pMdl = pArgs->MapApertureSegment.pMdl;

            for (UINT i = 0; i < pageCount; i++)
            {
                m_aperturePageTable[pageIndex + i] = MmGetMdlPfnArray(pMdl)[mdlPageOffset + i];
            }
        }

    }
    break;

    case DXGK_OPERATION_UNMAP_APERTURE_SEGMENT:
    {
        if (pArgs->MapApertureSegment.SegmentId == kApertureSegmentId)
        {
            size_t pageIndex = pArgs->MapApertureSegment.OffsetInPages;
            size_t pageCount = pArgs->MapApertureSegment.NumberOfPages;

            NT_ASSERT(pageIndex + pageCount <= kApertureSegmentPageCount);

            while (pageCount--)
            {
                m_aperturePageTable[pageIndex++] = 0;
            }
        }
    }

    break;

    case DXGK_OPERATION_FILL:
    {
        RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)pArgs->Fill.hAllocation;
        pRosKmdAllocation;

        DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Filling at %lx with %lx size %lx\n",
            pArgs->Fill.Destination.SegmentAddress,
            pArgs->Fill.FillPattern,
            pArgs->Fill.FillSize);

        if (pArgs->DmaSize < sizeof(DXGKARG_BUILDPAGINGBUFFER))
        {
            return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
        }
        else
        {
            *((DXGKARG_BUILDPAGINGBUFFER *)pArgs->pDmaBuffer) = *pArgs;

            pDmaBufPos += sizeof(DXGKARG_BUILDPAGINGBUFFER);
        }
    }
    break;

    case DXGK_OPERATION_DISCARD_CONTENT:
    {
        // do nothing
    }
    break;

    case DXGK_OPERATION_TRANSFER:
    {
        if (pArgs->DmaSize < sizeof(DXGKARG_BUILDPAGINGBUFFER))
        {
            return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
        }
        else
        {
            *((DXGKARG_BUILDPAGINGBUFFER *)pArgs->pDmaBuffer) = *pArgs;

            pDmaBufPos += sizeof(DXGKARG_BUILDPAGINGBUFFER);
        }
    }
    break;

    default:
    {
        NT_ASSERT(false);

        m_ErrorHit.m_UnSupportedPagingOp = 1;
        Status = STATUS_SUCCESS;
    }
    break;
    }

    //
    // Update pDmaBuffer to point past the last byte used.
    pArgs->pDmaBuffer = pDmaBufPos;

    // Record DMA buffer information only when it is newly used
    ROSDMABUFINFO * pDmaBufInfo = (ROSDMABUFINFO *)pArgs->pDmaBufferPrivateData;
    if (pDmaBufInfo && (pArgs->DmaSize == ROSD_PAGING_BUFFER_SIZE))
    {
        pDmaBufInfo->m_DmaBufState.m_Value = 0;
        pDmaBufInfo->m_DmaBufState.m_bPaging = 1;

        pDmaBufInfo->m_pDmaBuffer = pDmaBufStart;
        pDmaBufInfo->m_DmaBufferSize = pArgs->DmaSize;
    }

    return Status;
}
NTSTATUS PrvCloneAuthorizedNBLAndInject(_Inout_ CLASSIFY_DATA** ppClassifyData,
                                        _Inout_ INJECTION_DATA** ppInjectionData)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> PrvCloneAuthorizedNBLAndInject()\n");

#endif /// DBG
   
   NT_ASSERT(ppClassifyData);
   NT_ASSERT(ppInjectionData);
   NT_ASSERT(*ppClassifyData);
   NT_ASSERT(*ppInjectionData);

   NTSTATUS                            status          = STATUS_SUCCESS;
   FWPS_INCOMING_VALUES*               pClassifyValues = (FWPS_INCOMING_VALUES*)(*ppClassifyData)->pClassifyValues;
   FWPS_INCOMING_METADATA_VALUES*      pMetadata       = (FWPS_INCOMING_METADATA_VALUES*)(*ppClassifyData)->pMetadataValues;
   UINT32                              bytesRetreated  = 0;
   COMPARTMENT_ID                      compartmentID   = UNSPECIFIED_COMPARTMENT_ID;
   BOOLEAN                             isInbound       = FALSE;
   NET_BUFFER_LIST*                    pNetBufferList  = 0;
   PEND_AUTHORIZATION_COMPLETION_DATA* pCompletionData = 0;
   FWPS_TRANSPORT_SEND_PARAMS*         pSendParams     = 0;
   BYTE*                               pRemoteAddress  = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pCompletionData will be freed in completionFn using PendAuthorizationCompletionDataDestroy

   HLPR_NEW(pCompletionData,
            PEND_AUTHORIZATION_COMPLETION_DATA,
            WFPSAMPLER_CALLOUT_DRIVER_TAG);
   HLPR_BAIL_ON_ALLOC_FAILURE(pCompletionData,
                              status);

   HLPR_NEW(pSendParams,
            FWPS_TRANSPORT_SEND_PARAMS,
            WFPSAMPLER_CALLOUT_DRIVER_TAG);
   HLPR_BAIL_ON_ALLOC_FAILURE(pSendParams,
                              status);

#pragma warning(pop)

   KeInitializeSpinLock(&(pCompletionData->spinLock));

   pCompletionData->performedInline = FALSE;
   pCompletionData->pClassifyData   = *ppClassifyData;
   pCompletionData->pInjectionData  = *ppInjectionData;
   pCompletionData->pSendParams     = pSendParams;

   /// Responsibility for freeing this memory has been transferred to the pCompletionData
   *ppClassifyData = 0;

   *ppInjectionData = 0;

   pSendParams = 0;

   if(pCompletionData->pInjectionData->direction == FWP_DIRECTION_INBOUND)
      isInbound = TRUE;

   if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                     FWPS_METADATA_FIELD_COMPARTMENT_ID))
      compartmentID = (COMPARTMENT_ID)pMetadata->compartmentId;

   if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                     FWPS_METADATA_FIELD_IP_HEADER_SIZE))
      bytesRetreated = pMetadata->ipHeaderSize;

   if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                     FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE))
      bytesRetreated += pMetadata->transportHeaderSize;

   if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 ||
      pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6)
   {
      if(isInbound) /// NBL offset is at the start of the transport header ...
      {
         if(bytesRetreated)
         {
            /// so retreat (size of IP Header) to clone the whole NBL
            status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pCompletionData->pClassifyData->pPacket),
                                                   bytesRetreated,
                                                   0,
                                                   0);
            if(status != STATUS_SUCCESS)
            {
               DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                          DPFLTR_ERROR_LEVEL,
                          " !!!! PrvCloneAuthorizedNBLAndInject: NdisRetreatNetBufferDataStart() [status: %#x]\n",
                          status);

               HLPR_BAIL;
            }
         }
      }
   }
   else if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 ||
           pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6)
   {
      /// NBL offset is at the Transport Header, and no IP Header is present yet
      bytesRetreated = 0;

      isInbound = FALSE;
   }
   else
   {
      status = STATUS_FWP_INCOMPATIBLE_LAYER;

      HLPR_BAIL;
   }

   status = FwpsAllocateCloneNetBufferList((NET_BUFFER_LIST*)(pCompletionData->pClassifyData->pPacket),
                                           g_pNDISPoolData->nblPoolHandle,
                                           g_pNDISPoolData->nbPoolHandle,
                                           0,
                                           &pNetBufferList);

   if(bytesRetreated)
   {
      /// Advance the NBL offset so we are back at the expected position in the NET_BUFFER_LIST
      NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pCompletionData->pClassifyData->pPacket),
                                    bytesRetreated,
                                    FALSE,
                                    0);
   }

   if(status != STATUS_SUCCESS)
   {
      DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                 DPFLTR_ERROR_LEVEL,
                 " !!!! PrvCloneAuthorizedNBLAndInject : FwpsAllocateCloneNetBufferList() [status: %#x]\n",
                 status);

      HLPR_BAIL;
   }

   if(isInbound)
   {
      FWP_VALUE* pInterfaceIndex    = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues,
                                                                                &FWPM_CONDITION_INTERFACE_INDEX);
      FWP_VALUE* pSubInterfaceIndex = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues,
                                                                                &FWPM_CONDITION_SUB_INTERFACE_INDEX);
      IF_INDEX   interfaceIndex     = 0;
      IF_INDEX   subInterfaceIndex  = 0;

      if(pInterfaceIndex &&
         pInterfaceIndex->type == FWP_UINT32)
         interfaceIndex = (IF_INDEX)pInterfaceIndex->uint32;

      if(pSubInterfaceIndex &&
         pSubInterfaceIndex->type == FWP_UINT32)
         subInterfaceIndex = (IF_INDEX)pSubInterfaceIndex->uint32;

      status = FwpsInjectTransportReceiveAsync(pCompletionData->pInjectionData->injectionHandle,
                                               pCompletionData->pInjectionData->injectionContext,
                                               0,
                                               0,
                                               pCompletionData->pInjectionData->addressFamily,
                                               compartmentID,
                                               interfaceIndex,
                                               subInterfaceIndex,
                                               pNetBufferList,
                                               CompletePendAuthorization,
                                               pCompletionData);
   }
   else
   {
      UINT64     endpointHandle = 0;
      FWP_VALUE* pAddressValue  = 0;

      if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                        FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE))
         endpointHandle = pMetadata->transportEndpointHandle;

      pAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues,
                                                                &FWPM_CONDITION_IP_REMOTE_ADDRESS);
      if(pAddressValue)
      {
         if(pCompletionData->pInjectionData->addressFamily == AF_INET)
         {
            UINT32 tempAddress = htonl(pAddressValue->uint32);

#pragma warning(push)
#pragma warning(disable: 6014) /// pRemoteAddress will be freed in completionFn using PendAuthorizationCompletionDataDestroy

            HLPR_NEW_ARRAY(pRemoteAddress,
                           BYTE,
                           IPV4_ADDRESS_SIZE,
                           WFPSAMPLER_CALLOUT_DRIVER_TAG);
            HLPR_BAIL_ON_ALLOC_FAILURE(pRemoteAddress,
                                       status);

#pragma warning(pop)

            RtlCopyMemory(pRemoteAddress,
                          &tempAddress,
                          IPV4_ADDRESS_SIZE);
         }
         else
         {

#pragma warning(push)
#pragma warning(disable: 6014) /// pRemoteAddress will be freed in completionFn using PendAuthorizationCompletionDataDestroy

            HLPR_NEW_ARRAY(pRemoteAddress,
                           BYTE,
                           IPV6_ADDRESS_SIZE,
                           WFPSAMPLER_CALLOUT_DRIVER_TAG);
            HLPR_BAIL_ON_ALLOC_FAILURE(pRemoteAddress,
                                       status);

#pragma warning(pop)

            RtlCopyMemory(pRemoteAddress,
                          pAddressValue->byteArray16->byteArray16,
                          IPV6_ADDRESS_SIZE);

            if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                              FWPS_METADATA_FIELD_REMOTE_SCOPE_ID))
               pCompletionData->pSendParams->remoteScopeId = pMetadata->remoteScopeId;
         }

         pCompletionData->pSendParams->remoteAddress = pRemoteAddress;
      }

      pCompletionData->refCount = KrnlHlprNBLGetRequiredRefCount(pNetBufferList);

      status = FwpsInjectTransportSendAsync(pCompletionData->pInjectionData->injectionHandle,
                                            pCompletionData->pInjectionData->injectionContext,
                                            endpointHandle,
                                            0,
                                            pCompletionData->pSendParams,
                                            pCompletionData->pInjectionData->addressFamily,
                                            compartmentID,
                                            pNetBufferList,
                                            CompletePendAuthorization,
                                            pCompletionData);
   }

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS)
   {
      if(pNetBufferList)
      {
         FwpsFreeCloneNetBufferList(pNetBufferList,
                                    0);

         pNetBufferList = 0;
      }

      if(pCompletionData)
         PendAuthorizationCompletionDataDestroy(&pCompletionData,
                                                TRUE);
   }

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- PrvCloneAuthorizedNBLAndInject() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
}
Example #30
0
NTSTATUS TdProtectNameCallback (
    _In_ PTD_PROTECTNAME_INPUT pProtectName
)
{
    NTSTATUS Status = STATUS_SUCCESS;

    if (!pProtectName) {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
            "ObCallbackTest: TdProtectNameCallback: name to protect/filter NULL pointer\n"
        );
    }
    else {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
            "ObCallbackTest: TdProtectNameCallback: entering name to protect/filter %ls\n", pProtectName->Name
        );
    }
    KeAcquireGuardedMutex (&TdCallbacksMutex);

    // Need to copy out the name and then set the flag to filter
    // This will allow process creation to watch for the process to be created and get the PID
    // and then prevent any other process from opening up that PID to terminate

    memcpy(TdwProtectName, pProtectName->Name, sizeof(TdwProtectName));

    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: name copied     %ls\n", TdwProtectName
    );

    // Need to enable the OB callbacks
    // once the process is matched to a newly created process, the callbacks will protect the process
    if (bCallbacksInstalled == FALSE) {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
            "ObCallbackTest: TdProtectNameCallback: installing callbacks\n"
        );

        // Setup the Ob Registration calls

        CBOperationRegistrations[0].ObjectType = PsProcessType;
        CBOperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_CREATE;
        CBOperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_DUPLICATE;
        CBOperationRegistrations[0].PreOperation = CBTdPreOperationCallback;
        CBOperationRegistrations[0].PostOperation = CBTdPostOperationCallback;

        CBOperationRegistrations[1].ObjectType = PsThreadType;
        CBOperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_CREATE;
        CBOperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_DUPLICATE;
        CBOperationRegistrations[1].PreOperation = CBTdPreOperationCallback;
        CBOperationRegistrations[1].PostOperation = CBTdPostOperationCallback;


        RtlInitUnicodeString (&CBAltitude, L"1000");

        CBObRegistration.Version                    = OB_FLT_REGISTRATION_VERSION;
        CBObRegistration.OperationRegistrationCount = 2;
        CBObRegistration.Altitude                   = CBAltitude;
        CBObRegistration.RegistrationContext        = &CBCallbackRegistration;
        CBObRegistration.OperationRegistration      = CBOperationRegistrations;


        Status = ObRegisterCallbacks (
            &CBObRegistration,
            &pCBRegistrationHandle       // save the registration handle to remove callbacks later
        );

        if (!NT_SUCCESS (Status))   {
            DbgPrintEx (
                DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
                "ObCallbackTest: installing OB callbacks failed  status 0x%x\n", Status
            );
            KeReleaseGuardedMutex (&TdCallbacksMutex); // Release the lock before exit
            goto Exit;
        }
        bCallbacksInstalled = TRUE;

    }


    KeReleaseGuardedMutex (&TdCallbacksMutex);


    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: TdProtectNameCallback: name to protect/filter %ls\n", TdwProtectName
    );

Exit:
    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: TdProtectNameCallback: exiting  status 0x%x\n", Status
    );
    return Status;
}