Example #1
0
HWINSTA APIENTRY
NtUserCreateWindowStation(
   POBJECT_ATTRIBUTES ObjectAttributes,
   ACCESS_MASK dwDesiredAccess,
   DWORD Unknown2,
   DWORD Unknown3,
   DWORD Unknown4,
   DWORD Unknown5,
   DWORD Unknown6)
{
   UNICODE_STRING WindowStationName;
   PWINSTATION_OBJECT WindowStationObject;
   HWINSTA WindowStation;
   NTSTATUS Status;

   TRACE("NtUserCreateWindowStation called\n");

   Status = ObOpenObjectByName(
               ObjectAttributes,
               ExWindowStationObjectType,
               UserMode,
               NULL,
               dwDesiredAccess,
               NULL,
               (PVOID*)&WindowStation);

   if (NT_SUCCESS(Status))
   {
       TRACE("NtUserCreateWindowStation opened window station %wZ\n", ObjectAttributes->ObjectName);
       return (HWINSTA)WindowStation;
   }

   /*
    * No existing window station found, try to create new one
    */

   /* Capture window station name */
   _SEH2_TRY
   {
      ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1);
      Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName, ObjectAttributes->ObjectName);
   }
   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
   {
      Status =_SEH2_GetExceptionCode();
   }
   _SEH2_END

   if (! NT_SUCCESS(Status))
   {
      ERR("Failed reading capturing window station name\n");
      SetLastNtError(Status);
      return NULL;
   }

   /* Create the window station object */
   Status = ObCreateObject(
               UserMode,
               ExWindowStationObjectType,
               ObjectAttributes,
               UserMode,
               NULL,
               sizeof(WINSTATION_OBJECT),
               0,
               0,
               (PVOID*)&WindowStationObject);

   if (!NT_SUCCESS(Status))
   {
      ERR("ObCreateObject failed for window station %wZ\n", &WindowStationName);
      ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING);
      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
      return 0;
   }

   Status = ObInsertObject(
               (PVOID)WindowStationObject,
               NULL,
               dwDesiredAccess,
               0,
               NULL,
               (PVOID*)&WindowStation);

   if (!NT_SUCCESS(Status))
   {
      ERR("ObInsertObject failed for window station %wZ\n", &WindowStationName);
      ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING);
      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
      ObDereferenceObject(WindowStationObject);
      return 0;
   }

   /* Initialize the window station */
   RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT));

   KeInitializeSpinLock(&WindowStationObject->Lock);
   InitializeListHead(&WindowStationObject->DesktopListHead);
   Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable);
   WindowStationObject->SystemMenuTemplate = (HANDLE)0;
   WindowStationObject->Name = WindowStationName;
   WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId;

   if (InputWindowStation == NULL)
   {
       TRACE("Initializeing input window station\n");
      InputWindowStation = WindowStationObject;

      InitCursorImpl();
   }

   TRACE("NtUserCreateWindowStation created object 0x%x with name %wZ handle 0x%x\n",
          WindowStation, &WindowStationObject->Name, WindowStation);
   return WindowStation;
}
Example #2
0
/*
 * @implemented
 */
VOID
EXPORT
NdisRegisterProtocol(
    OUT PNDIS_STATUS                    Status,
    OUT PNDIS_HANDLE                    NdisProtocolHandle,
    IN  PNDIS_PROTOCOL_CHARACTERISTICS  ProtocolCharacteristics,
    IN  UINT                            CharacteristicsLength)
/*
 * FUNCTION: Registers an NDIS driver's ProtocolXxx entry points
 * ARGUMENTS:
 *     Status                  = Address of buffer for status information
 *     NdisProtocolHandle      = Address of buffer for handle used to identify the driver
 *     ProtocolCharacteristics = Pointer to NDIS_PROTOCOL_CHARACTERISTICS structure
 *     CharacteristicsLength   = Size of structure which ProtocolCharacteristics targets
 * NOTES:
 *     - you *must* set NdisProtocolHandle before doing anything that could wind up
 *       getting BindAdapterHandler, as it will probably call OpenAdapter with this handle
 *     - the above implies that the initialization of the protocol block must be complete
 *       by then
 * TODO:
 *     - break this function up - probably do a 'ndisRefreshProtocolBindings' function
 *     - make this thing able to handle >1 protocol
 */
{
  PPROTOCOL_BINDING Protocol;
  NTSTATUS NtStatus;
  UINT MinSize;
  PNET_PNP_EVENT PnPEvent;

  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));

  *NdisProtocolHandle = NULL;

  /* first validate the PROTOCOL_CHARACTERISTICS */
  switch (ProtocolCharacteristics->MajorNdisVersion)
    {
    case 0x03:
      /* we don't really want to support ndis3 drivers - so we complain for now */
      NDIS_DbgPrint(MID_TRACE, ("NDIS 3 protocol attempting to register\n"));
      MinSize = sizeof(NDIS30_PROTOCOL_CHARACTERISTICS);
      break;

    case 0x04:
      MinSize = sizeof(NDIS40_PROTOCOL_CHARACTERISTICS);
      break;

    case 0x05:
      MinSize = sizeof(NDIS50_PROTOCOL_CHARACTERISTICS);
      break;

    default:
      *Status = NDIS_STATUS_BAD_VERSION;
      NDIS_DbgPrint(MIN_TRACE, ("Incorrect characteristics size\n"));
      return;
    }

  if (CharacteristicsLength < MinSize)
    {
      NDIS_DbgPrint(MIN_TRACE, ("Bad protocol characteristics.\n"));
      *Status = NDIS_STATUS_BAD_CHARACTERISTICS;
      return;
    }

  /* set up the protocol block */
  Protocol = ExAllocatePool(NonPagedPool, sizeof(PROTOCOL_BINDING));
  if (!Protocol)
    {
      NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
      *Status = NDIS_STATUS_RESOURCES;
      return;
    }

  RtlZeroMemory(Protocol, sizeof(PROTOCOL_BINDING));
  RtlCopyMemory(&Protocol->Chars, ProtocolCharacteristics, MinSize);

  NtStatus = RtlUpcaseUnicodeString(&Protocol->Chars.Name, &ProtocolCharacteristics->Name, TRUE);
  if (!NT_SUCCESS(NtStatus))
    {
      NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
      ExFreePool(Protocol);
      *Status = NDIS_STATUS_RESOURCES;
      return;
    }

  KeInitializeSpinLock(&Protocol->Lock);

  InitializeListHead(&Protocol->AdapterListHead);

  /* We must set this before the call to ndisBindMiniportsToProtocol because the protocol's
   * BindAdapter handler might need it */

  *NdisProtocolHandle = Protocol;

  ndisBindMiniportsToProtocol(Status, Protocol);

  /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */
  PnPEvent = ProSetupPnPEvent(NetEventBindsComplete, NULL, 0);
  if (PnPEvent)
  {
      if (Protocol->Chars.PnPEventHandler)
      {
          /* We call this with a NULL binding context because it affects all bindings */
          NtStatus = (*Protocol->Chars.PnPEventHandler)(NULL,
                                                        PnPEvent);

          /* FIXME: We don't support this yet */
          ASSERT(NtStatus != NDIS_STATUS_PENDING);
      }

      ExFreePool(PnPEvent);
  }

  if (*Status == NDIS_STATUS_SUCCESS) {
      ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock);
  } else {
      NDIS_DbgPrint(MIN_TRACE, ("Binding failed (%x)\n", *Status));
      ExFreePool(Protocol);
      *NdisProtocolHandle = NULL;
  }
}
Example #3
0
void sys_lock_init( sys_lock_t *lock )
{
	KeInitializeSpinLock( &lock->Lock );
	lock->irql = PASSIVE_LEVEL;
}
Example #4
0
NTSTATUS USBPcapCreateRootHubControlDevice(IN PDEVICE_EXTENSION hubExt,
                                           OUT PDEVICE_OBJECT *control,
                                           OUT USHORT *busId)
{
    UNICODE_STRING     ntDeviceName;
    UNICODE_STRING     symbolicLinkName;
    PDEVICE_OBJECT     controlDevice = NULL;
    PDEVICE_EXTENSION  controlExt = NULL;
    NTSTATUS           status;
    USHORT             id;
    PWCHAR             ntNameBuffer[MAX_NTNAME_LEN];
    PWCHAR             symbolicNameBuffer[MAX_SYMBOLIC_LEN];

    ASSERT(hubExt->deviceMagic == USBPCAP_MAGIC_ROOTHUB);

    /* Acquire the control device ID */
    id = (USHORT) InterlockedIncrement(&g_controlId);

    ntDeviceName.Length = 0;
    ntDeviceName.MaximumLength = MAX_NTNAME_LEN;
    ntDeviceName.Buffer = (PWSTR)ntNameBuffer;

    symbolicLinkName.Length = 0;
    symbolicLinkName.MaximumLength = MAX_SYMBOLIC_LEN;
    symbolicLinkName.Buffer = (PWSTR)symbolicNameBuffer;

    status = RtlUnicodeStringPrintf(&ntDeviceName,
                                    NTNAME_PREFIX L"%hu", id);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    status = RtlUnicodeStringPrintf(&symbolicLinkName,
                                    SYMBOLIC_PREFIX L"%hu", id);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    KdPrint(("Creating device %wZ (%wZ)\n",
            &ntDeviceName, &symbolicLinkName));

    status = IoCreateDeviceSecure(hubExt->pDrvObj,
                                  sizeof(DEVICE_EXTENSION),
                                  &ntDeviceName,
                                  FILE_DEVICE_UNKNOWN,
                                  FILE_DEVICE_SECURE_OPEN,
                                  TRUE, /* Exclusive device */
                                  &SDDL_DEVOBJ_SYS_ALL_ADM_ALL_EVERYONE_ANY,
                                  NULL,
                                  &controlDevice);

    if (NT_SUCCESS(status))
    {
        controlDevice->Flags |= DO_DIRECT_IO;

        status = IoCreateSymbolicLink(&symbolicLinkName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
            IoDeleteDevice(controlDevice);
            KdPrint(("IoCreateSymbolicLink failed %x\n", status));
            return status;
        }

        controlExt = (PDEVICE_EXTENSION)controlDevice->DeviceExtension;
        controlExt->deviceMagic      = USBPCAP_MAGIC_CONTROL;
        controlExt->pThisDevObj      = controlDevice;
        controlExt->pNextDevObj      = NULL;
        controlExt->pDrvObj          = hubExt->pDrvObj;

        IoInitializeRemoveLock(&controlExt->removeLock, 0, 0, 0);
        controlExt->parentRemoveLock = &hubExt->removeLock;

        /* Initialize USBPcap control context */
        controlExt->context.control.id             = id;
        controlExt->context.control.pRootHubObject = hubExt->pThisDevObj;


        KeInitializeSpinLock(&controlExt->context.control.csqSpinLock);
        InitializeListHead(&controlExt->context.control.lePendIrp);
        status = IoCsqInitialize(&controlExt->context.control.ioCsq,
                                 DkCsqInsertIrp, DkCsqRemoveIrp,
                                 DkCsqPeekNextIrp, DkCsqAcquireLock,
                                 DkCsqReleaseLock, DkCsqCompleteCanceledIrp);
        if (!NT_SUCCESS(status))
        {
            DkDbgVal("Error initialize Cancel-safe queue!", status);
            goto End;
        }

        controlDevice->Flags &= ~DO_DEVICE_INITIALIZING;
    }
    else
    {
        KdPrint(("IoCreateDevice failed %x\n", status));
    }

End:
    if ((!NT_SUCCESS(status)) || (controlExt == NULL))
    {
        if (controlDevice != NULL)
        {
            IoDeleteSymbolicLink(&symbolicLinkName);
            IoDeleteDevice(controlDevice);
        }
    }
    else
    {
        IoAcquireRemoveLock(controlExt->parentRemoveLock, NULL);
        *control = controlDevice;
        *busId = id;
    }

    return status;
}
Example #5
0
static NTSTATUS
V4vCtrlAccept(XENV4V_EXTENSION *pde, XENV4V_CONTEXT *ctx, ULONG ioc, VOID *iob, ULONG iol, PIRP irp)
{
    NTSTATUS            status = STATUS_SUCCESS;
    LONG                val;
    V4V_INIT_VALUES     init;
    FILE_OBJECT        *pfo = NULL;
    XENV4V_CONTEXT     *actx;
    XENV4V_INSERT       ins = {FALSE};
    HANDLE              fh;
    HANDLE              rxe;
    V4V_ACCEPT_PRIVATE *priv;

    val = InterlockedExchangeAdd(&ctx->state, 0);
    if (val != XENV4V_STATE_LISTENING) {
        TraceWarning(("state not LISTENING, cannot complete accept request\n"));
        return STATUS_INVALID_DEVICE_REQUEST;
    }    

    // Handle 32b/64b thunk sructures here and test input
#if defined(_WIN64)
    if (ioc == V4V_IOCTL_ACCEPT_32)
    {
        V4V_ACCEPT_VALUES_32 *avs32 = (V4V_ACCEPT_VALUES_32*)iob;

        if (iol != sizeof(V4V_ACCEPT_VALUES_32)) {
            TraceError(("invalid accept values.\n"));
            return STATUS_INVALID_PARAMETER;
        }        
        fh  = avs32->fileHandle;
        rxe = avs32->rxEvent;
        priv = (V4V_ACCEPT_PRIVATE*)((UCHAR*)avs32 + FIELD_OFFSET(V4V_ACCEPT_VALUES_32, priv));
    }
    else
#endif
    {
        V4V_ACCEPT_VALUES *avs = (V4V_ACCEPT_VALUES*)iob;

        UNREFERENCED_PARAMETER(ioc);

        if (iol != sizeof(V4V_ACCEPT_VALUES)) {
            TraceError(("invalid accept values.\n"));
            return STATUS_INVALID_PARAMETER;
        }        
        fh  = avs->fileHandle;
        rxe = avs->rxEvent;
        priv = (V4V_ACCEPT_PRIVATE*)((UCHAR*)avs + FIELD_OFFSET(V4V_ACCEPT_VALUES, priv));
    }

    // Any IRPs that are queued are given a sanity initialization
    V4vInitializeIrp(irp);

    // Get a reference to the file object for the handle
    status = ObReferenceObjectByHandle(fh,
                                       0,
                                       *IoFileObjectType,
                                       irp->RequestorMode,
                                       &pfo,
                                       NULL);
    if (!NT_SUCCESS(status)) {
        TraceError(("failed to get a reference to the accepter file object - error: 0x%x\n", status));
        return status;
    }
    actx = (XENV4V_CONTEXT*)pfo->FsContext;
    ObDereferenceObject(pfo);

    // Store the referenced acceptor context in the IOCTL buffer so we can access it at > PASSIVE later.
    V4vAddRefContext(pde, actx);
#if defined(_WIN64)
    priv->q.a = (ULONG64)actx;
#else
    priv->d.a = (ULONG32)actx;
#endif

    // Do the base initialization of the file object context
    init.rxEvent = rxe;
    init.ringLength = ctx->ringLength; // shared ring length
    status = V4vCtrlInitializeFile(actx, &init, irp);
    if (!NT_SUCCESS(status)) {
        V4vReleaseContext(pde, actx);
        TraceError(("failed to initialize the accepter file object - error: 0x%x\n", status));
        return status;
    }

    // Now initialize the accepter specific state and associate the accepter
    // with the listener context and ring.
    KeInitializeSpinLock(&actx->u.accepter.dataLock);
    actx->u.accepter.dataList = NULL;
    actx->u.accepter.dataTail = NULL;
    V4vAddRefContext(pde, ctx);
    V4vAddRefRing(pde, ctx->ringObject);
    actx->u.accepter.listenerContext = ctx;
    actx->ringObject = ctx->ringObject;

    // Now it becomes an accepter type for ever more
    InterlockedExchange(&actx->type, XENV4V_TYPE_ACCEPTER);

    // After this transition, we will wait for a SYN (may be one in the queue already).
    InterlockedExchange(&actx->state, XENV4V_STATE_ACCEPTING);

    // Flag it
    irp->Tail.Overlay.DriverContext[0] = 
        (PVOID)(ULONG_PTR)(XENV4V_PEEK_STREAM|XENV4V_PEEK_ACCEPT|XENV4V_PEEK_IOCTL);

    // Always queue it to the back and marks it pending. If it fails to be queued then
    // the user mode call will close the new handle.
    status = IoCsqInsertIrpEx(&pde->csqObject, irp, NULL, &ins);
    if (NT_SUCCESS(status)) {
        status = STATUS_PENDING;
        // Drive any accepts
        V4vDoAccepts(pde, ctx);
    }

    return status;
}
Example #6
0
void datapipe_init(datapipe_t *dp)
{
	dp->first = dp->last = NULL;
	KeInitializeSpinLock(&dp->guard);
}
Example #7
0
NTSTATUS
DriverEntry(
   IN  PDRIVER_OBJECT  driverObject,
   IN  PUNICODE_STRING registryPath
   )
{
   NTSTATUS status = STATUS_SUCCESS;
   UNICODE_STRING deviceName;
   HANDLE threadHandle;

   TLInspectLoadConfig(registryPath);

   if ((configInspectRemoteAddrV4 == NULL) && 
       (configInspectRemoteAddrV6 == NULL))
   {
      status = STATUS_DEVICE_CONFIGURATION_ERROR;
      goto Exit;
   }

   RtlInitUnicodeString(
      &deviceName,
      L"\\Device\\StreamEitor"
      );

   status = IoCreateDevice(
               driverObject, 
               0, 
               &deviceName, 
               FILE_DEVICE_NETWORK, 
               0, 
               FALSE, 
               &gDeviceObject
               );
   if (!NT_SUCCESS(status))
   {
      goto Exit;
   }

   status = FwpsInjectionHandleCreate0(
               AF_UNSPEC,
               FWPS_INJECTION_TYPE_TRANSPORT,
               &gInjectionHandle
               );

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

   InitializeListHead(&gConnList);
   KeInitializeSpinLock(&gConnListLock);   

   InitializeListHead(&gPacketQueue);
   KeInitializeSpinLock(&gPacketQueueLock);  

   KeInitializeEvent(
      &gWorkerEvent,
      NotificationEvent,
      FALSE
      );

   status = TLInspectRegisterCallouts(
               gDeviceObject
               );

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

   status = PsCreateSystemThread(
               &threadHandle,
               THREAD_ALL_ACCESS,
               NULL,
               NULL,
               NULL,
               TLInspectWorker,
               NULL
               );

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

   status = ObReferenceObjectByHandle(
               threadHandle,
               0,
               NULL,
               KernelMode,
               &gThreadObj,
               NULL
               );
   ASSERT(NT_SUCCESS(status));

   ZwClose(threadHandle);

   driverObject->DriverUnload = DriverUnload;

Exit:
   
   if (!NT_SUCCESS(status))
   {
      if (gEngineHandle != NULL)
      {
         TLInspectUnregisterCallouts();
      }
      if (gInjectionHandle != NULL)
      {
         FwpsInjectionHandleDestroy0(gInjectionHandle);
      }
      if (gDeviceObject)
      {
         IoDeleteDevice(gDeviceObject);
      }
      
      if(gRegistryKey != NULL)
      {
        ZwClose(gRegistryKey);
      }
   }

   return status;
}
/*! \brief Initializes the KDB symbols implementation.
 *
 * \param DispatchTable         Pointer to the KD dispatch table
 * \param BootPhase             Phase of initialization
 */
VOID
NTAPI
KdbInitialize(
    PKD_DISPATCH_TABLE DispatchTable,
    ULONG BootPhase)
{
    PCHAR p1, p2;
    SHORT Found = FALSE;
    CHAR YesNo;
    PLDR_DATA_TABLE_ENTRY LdrEntry;

    DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase);

    LoadSymbols = FALSE;

#if DBG
    /* Load symbols only if we have 96Mb of RAM or more */
    if (MmNumberOfPhysicalPages >= 0x6000)
        LoadSymbols = TRUE;
#endif

    if (BootPhase == 0)
    {
        /* Write out the functions that we support for now */
        DispatchTable->KdpInitRoutine = KdpKdbgInit;
        DispatchTable->KdpPrintRoutine = KdbDebugPrint;

        /* Register as a Provider */
        InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);

        /* Perform actual initialization of symbol module */
        //NtoskrnlModuleObject->PatchInformation = NULL;
        //LdrHalModuleObject->PatchInformation = NULL;

        InitializeListHead(&SymbolFileListHead);
        KeInitializeSpinLock(&SymbolFileListLock);

        /* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
        * /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
        ASSERT(KeLoaderBlock);
        p1 = KeLoaderBlock->LoadOptions;
        while('\0' != *p1 && NULL != (p2 = strchr(p1, '/')))
        {
            p2++;
            Found = 0;
            if (0 == _strnicmp(p2, "LOADSYMBOLS", 11))
            {
                Found = +1;
                p2 += 11;
            }
            else if (0 == _strnicmp(p2, "NOLOADSYMBOLS", 13))
            {
                Found = -1;
                p2 += 13;
            }
            if (0 != Found)
            {
                while (isspace(*p2))
                {
                    p2++;
                }
                if ('=' == *p2)
                {
                    p2++;
                    while (isspace(*p2))
                    {
                        p2++;
                    }
                    YesNo = toupper(*p2);
                    if ('N' == YesNo || 'F' == YesNo || '0' == YesNo)
                    {
                        Found = -1 * Found;
                    }
                }
                LoadSymbols = (0 < Found);
            }
            p1 = p2;
        }

        RosSymInit(&KdbpRosSymCallbacks);
    }
    else if (BootPhase == 3)
    {
        /* Load symbols for NTOSKRNL.EXE.
           It is always the first module in PsLoadedModuleList. KeLoaderBlock can't be used here as its content is just temporary. */
        LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
        KdbSymProcessSymbols(LdrEntry);

        /* Also load them for HAL.DLL. */
        LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
        KdbSymProcessSymbols(LdrEntry);

        KdbpSymbolsInitialized = TRUE;
    }
}
Example #9
0
NTSTATUS
AWEAllocCreate(IN PDEVICE_OBJECT DeviceObject,
	       IN PIRP Irp)
{
  PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);

  KdPrint(("AWEAlloc: Create.\n"));

  PAGED_CODE();

  io_stack->FileObject->FsContext2 =
    ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_CONTEXT), POOL_TAG);

  if (io_stack->FileObject->FsContext2 == NULL)
    {
      KdPrint(("AWEAlloc: Pool allocation failed.\n"));

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

  RtlZeroMemory(io_stack->FileObject->FsContext2, sizeof(OBJECT_CONTEXT));

  io_stack->FileObject->Flags |= FO_DELETE_ON_CLOSE | FO_TEMPORARY_FILE;

  io_stack->FileObject->ReadAccess = TRUE;
  io_stack->FileObject->WriteAccess = TRUE;
  io_stack->FileObject->DeleteAccess = TRUE;
  io_stack->FileObject->SharedRead = TRUE;
  io_stack->FileObject->SharedWrite = FALSE;
  io_stack->FileObject->SharedDelete = FALSE;

  KeInitializeSpinLock
    (&((POBJECT_CONTEXT)io_stack->FileObject->FsContext2)->IOLock);

  MmResetDriverPaging((PVOID)(ULONG_PTR)DriverEntry);

  if (io_stack->FileObject->FileName.Length != 0)
    {
      NTSTATUS status;

      KdPrint(("AWEAlloc: Image file requested: '%.*ws'.\n",
	       (int)(io_stack->FileObject->FileName.Length /
		     sizeof(*io_stack->FileObject->FileName.Buffer)),
	       io_stack->FileObject->FileName.Buffer));

      status =
	AWEAllocLoadImageFile((POBJECT_CONTEXT)
			      io_stack->FileObject->FsContext2,
			      &Irp->IoStatus,
			      &io_stack->FileObject->FileName);

      IoCompleteRequest(Irp, IO_NO_INCREMENT); 

      KdPrint(("AWEAlloc: Image file status: %#x.\n", status));

      if (!NT_SUCCESS(status))
	AWEAllocLogError(AWEAllocDriverObject,
			 0,
			 0,
			 NULL,
			 0,
			 4000,
			 status,
			 401,
			 status,
			 0,
			 0,
			 NULL,
			 L"Image file failed.");

      return status;
    }

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

  return STATUS_SUCCESS;
}
Example #10
0
File: main.c Project: jpassing/cfix
static NTSTATUS CfixkrsCallRoutineIoctl(
	__in PVOID Buffer,
	__in ULONG InputBufferLength,
	__in ULONG OutputBufferLength,
	__out PULONG BytesWritten
	)
{
	CFIXKRP_REPORT_CHANNEL Channel;
	PCFIXKRP_DRIVER_CONNECTION DriverConnection;
	PCFIXKR_IOCTL_CALL_ROUTINE_REQUEST Request;
	PCFIXKR_IOCTL_CALL_ROUTINE_RESPONSE Response;
	NTSTATUS Status;

	ASSERT( BytesWritten );

	*BytesWritten = 0;

	//
	// Validate parameters.
	//
	if ( ! Buffer ||
		 InputBufferLength  < sizeof( CFIXKR_IOCTL_CALL_ROUTINE_REQUEST ) ||
		 OutputBufferLength < sizeof( CFIXKR_IOCTL_CALL_ROUTINE_RESPONSE ) )
	{
		return STATUS_INVALID_PARAMETER;
	}

	Request = ( PCFIXKR_IOCTL_CALL_ROUTINE_REQUEST ) Buffer;
	Response = ( PCFIXKR_IOCTL_CALL_ROUTINE_RESPONSE ) Buffer;

	if ( Request->DriverBaseAddress == 0 )
	{
		return STATUS_INVALID_PARAMETER;
	}

	if ( Request->Dispositions.FailedAssertion > CfixAbort ||
		 Request->Dispositions.UnhandledException > CfixAbort )
	{
		return STATUS_INVALID_PARAMETER;
	}

	Channel.Signature						= CFIXKRP_REPORT_CHANNEL_SIGNATURE;
	Channel.Dispositions.FailedAssertion	= Request->Dispositions.FailedAssertion;
	Channel.Dispositions.UnhandledException = Request->Dispositions.UnhandledException;
	KeInitializeSpinLock( &Channel.EventBuffer.Lock );

	//
	// Event structures will be appended to the output buffer
	// after the end of the CFIXKR_IOCTL_CALL_ROUTINE_RESPONSE struct.
	//
	// We can thus use the buffer to directly write events to.
	//
	Channel.EventBuffer.BufferSize			= 
		OutputBufferLength - sizeof( CFIXKR_IOCTL_CALL_ROUTINE_RESPONSE );
	Channel.EventBuffer.BufferLength		= 0;
	Channel.EventBuffer.BufferTruncated		= FALSE;
	Channel.EventBuffer.Buffer				= 
		( PUCHAR ) Buffer + sizeof( CFIXKR_IOCTL_CALL_ROUTINE_RESPONSE );
	Channel.EventBuffer.EventCount			= 0;

	Channel.TlsValue = ( PVOID ) ( ULONG_PTR ) Request->TlsValue;

	//
	// Try to lookup connection to this driver.
	//
	Status = CfixkrpLookupDriverConnection(
		Request->DriverBaseAddress,
		&DriverConnection );
	if ( ! NT_SUCCESS( Status ) )
	{
		return Status;
	}

	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	Status = CfixkrpCallRoutineDriverConnection(
		DriverConnection,
		Request->FixtureKey,
		Request->RoutineKey,
		&Channel,
		&Response->RoutineRanToCompletion,
		&Response->AbortRun );
	if ( NT_SUCCESS( Status ) )
	{
		//
		// Initialize the remaining parts of the response. The events
		// have already been written to the buffer.
		//
		ASSERT( Channel.EventBuffer.BufferLength <= Channel.EventBuffer.BufferSize );
		ASSERT( ( Channel.EventBuffer.BufferLength % 8 ) == 0 );

		Response->Events.Count = Channel.EventBuffer.EventCount;
		Response->Events.Flags = Channel.EventBuffer.BufferTruncated
			? CFIXKR_CALL_ROUTINE_FLAG_EVENTS_TRUNCATED
			: 0;

		Response->TlsValue = ( ULONG_PTR ) Channel.TlsValue;

		*BytesWritten = sizeof( CFIXKR_IOCTL_CALL_ROUTINE_RESPONSE ) +
			Channel.EventBuffer.BufferLength;
	}

	CfixkrpDereferenceConnection( DriverConnection );

	ASSERT( *BytesWritten <= OutputBufferLength );

	return Status;
}
Example #11
0
BOOLEAN
NTAPI
INIT_FUNCTION
PoInitSystem(IN ULONG BootPhase)
{
    PVOID NotificationEntry;
    PCHAR CommandLine;
    BOOLEAN ForceAcpiDisable = FALSE;

    /* Check if this is phase 1 init */
    if (BootPhase == 1)
    {
        /* Register power button notification */
        IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                       PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                       (PVOID)&GUID_DEVICE_SYS_BUTTON,
                                       IopRootDeviceNode->
                                       PhysicalDeviceObject->DriverObject,
                                       PopAddRemoveSysCapsCallback,
                                       NULL,
                                       &NotificationEntry);
        
        /* Register lid notification */
        IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                       PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                       (PVOID)&GUID_DEVICE_LID,
                                       IopRootDeviceNode->
                                       PhysicalDeviceObject->DriverObject,
                                       PopAddRemoveSysCapsCallback,
                                       NULL,
                                       &NotificationEntry);
        return TRUE;
    }

    /* Get the Command Line */
    CommandLine = KeLoaderBlock->LoadOptions;

    /* Upcase it */
    _strupr(CommandLine);

    /* Check for ACPI disable */
    if (strstr(CommandLine, "NOACPI")) ForceAcpiDisable = TRUE;

    if (ForceAcpiDisable)
    {
        /* Set the ACPI State to False if it's been forced that way */
        PopAcpiPresent = FALSE;
    }
    else
    {
        /* Otherwise check if the LoaderBlock has a ACPI Table  */
        PopAcpiPresent = KeLoaderBlock->Extension->AcpiTable != NULL ? TRUE : FALSE;
    }

    
    /* Initialize volume support */
    InitializeListHead(&PopVolumeDevices);
    KeInitializeGuardedMutex(&PopVolumeLock);
    
    /* Initialize support for dope */
    KeInitializeSpinLock(&PopDopeGlobalLock);

    /* Initialize support for shutdown waits and work-items */
    PopInitShutdownList();

    return TRUE;
}
Example #12
0
NTSTATUS
ExCreateCallback (
    __deref_out PCALLBACK_OBJECT * CallbackObject,
    __in POBJECT_ATTRIBUTES ObjectAttributes,
    __in BOOLEAN Create,
    __in BOOLEAN AllowMultipleCallbacks
    )

/*++

Routine Description:

    This function opens a callback object with the specified callback
    object. If the callback object does not exist or it is a NULL then
    a callback object will be created if create is TRUE. If a callbackobject
    is created it will only support multiple registered callbacks if
    AllowMulitipleCallbacks is TRUE.

Arguments:

    CallbackObject - Supplies a pointer to a variable that will receive the
        Callback object.

    CallbackName  - Supplies a pointer to a object name that will receive the

    Create - Supplies a flag which indicates whether a callback object will
        be created or not .

    AllowMultipleCallbacks - Supplies a flag which indicates only support
        multiple registered callbacks.

Return Value:

    NTSTATUS.

--*/

{
    PCALLBACK_OBJECT cbObject;
    NTSTATUS Status;
    HANDLE Handle;

    PAGED_CODE();

    //
    // Initializing cbObject & Handle is not needed for correctness but without
    // it the compiler cannot compile this code W4 to check for use of
    // uninitialized variables.
    //

    Handle = NULL;
    cbObject = NULL;

    //
    // If named callback, open handle to it
    //

    if (ObjectAttributes->ObjectName) {
        Status = ObOpenObjectByName(ObjectAttributes,
                                    ExCallbackObjectType,
                                    KernelMode,
                                    NULL,
                                    0,   // DesiredAccess,
                                    NULL,
                                    &Handle);
    } else {
        Status = STATUS_UNSUCCESSFUL;
    }

    //
    // If not opened, check if callback should be created
    //

    if (!NT_SUCCESS(Status) && Create ) {

        Status = ObCreateObject(KernelMode,
                                ExCallbackObjectType,
                                ObjectAttributes,
                                KernelMode,
                                NULL,
                                sizeof(CALLBACK_OBJECT),
                                0,
                                0,
                                (PVOID *)&cbObject );

        if(NT_SUCCESS(Status)){

            //
            // Fill in structure signature
            //

            cbObject->Signature = 'llaC';

            //
            // It will support multiple registered callbacks if
            // AllowMultipleCallbacks is TRUE.
            //

            cbObject->AllowMultipleCallbacks = AllowMultipleCallbacks;

            //
            // Initialize CallbackObject queue.
            //

            InitializeListHead( &cbObject->RegisteredCallbacks );

            //
            // Initialize spinlock
            //

            KeInitializeSpinLock (&cbObject->Lock);


            //
            // Put the object in the root directory
            //

            Status = ObInsertObject (
                     cbObject,
                     NULL,
                     FILE_READ_DATA,
                     0,
                     NULL,
                     &Handle );

        }

    }

    if(NT_SUCCESS(Status)){

        //
        // Add one to callback object reference count.
        //

        Status = ObReferenceObjectByHandle (
                    Handle,
                    0,          // DesiredAccess
                    ExCallbackObjectType,
                    KernelMode,
                    &cbObject,
                    NULL
                    );

        ZwClose (Handle);
    }

    //
    // If success, returns a referenced pointer to the CallbackObject.
    //

    if (NT_SUCCESS(Status)) {
        *CallbackObject = cbObject;
    }

    return Status;
}
Example #13
0
/*
 * Allocates USBPCAP_DEVICE_DATA.
 */
static NTSTATUS USBPcapAllocateDeviceData(IN PDEVICE_EXTENSION pDevExt,
                                          IN PDEVICE_EXTENSION pParentDevExt)
{
    PUSBPCAP_DEVICE_DATA  pDeviceData;
    NTSTATUS              status = STATUS_SUCCESS;
    BOOLEAN               allocRoothubData;

    allocRoothubData = (pParentDevExt == NULL);

    /* Allocate USBPCAP_DEVICE_DATA */
    pDeviceData = ExAllocatePoolWithTag(NonPagedPool,
                                        sizeof(USBPCAP_DEVICE_DATA),
                                        DKPORT_MTAG);

    if (pDeviceData != NULL)
    {
        /* deviceAddress, port and isHub will be properly set up when
         * filter driver handles IRP_MN_START_DEVICE
         */

        pDeviceData->deviceAddress = 255; /* UNKNOWN */

        /* This will get changed to TRUE once the deviceAddress,
         * parentPort and isHub will be correctly set up.
         */
        pDeviceData->properData = FALSE;

        /* Since 0 is invalid connection index, set that here */
        pDeviceData->parentPort = 0;
        /* assume that roothub is a hub and all other devices are not. */
        pDeviceData->isHub = allocRoothubData;

        pDeviceData->previousChildren = NULL;

        if (allocRoothubData == FALSE)
        {
            /*
             * This is not a roothub, just get the roothub data pointer
             * and increment the reference count
             */
            pDeviceData->pRootData =
                pParentDevExt->context.usb.pDeviceData->pRootData;
            InterlockedIncrement(&pDeviceData->pRootData->refCount);
        }
        else
        {
            /* Allocate USBPCAP_ROOTHUB_DATA */
            pDeviceData->pRootData =
                ExAllocatePoolWithTag(NonPagedPool,
                                      sizeof(USBPCAP_ROOTHUB_DATA),
                                      DKPORT_MTAG);
            if (pDeviceData->pRootData != NULL)
            {
                /* Initialize empty buffer */
                KeInitializeSpinLock(&pDeviceData->pRootData->bufferLock);
                pDeviceData->pRootData->buffer = NULL;
                pDeviceData->pRootData->readOffset = 0;
                pDeviceData->pRootData->writeOffset = 0;
                pDeviceData->pRootData->bufferSize = 0;

                /* Initialize default snaplen size */
                pDeviceData->pRootData->snaplen = USBPCAP_DEFAULT_SNAP_LEN;

                /* Setup initial filtering state to FALSE */
                memset(&pDeviceData->pRootData->filter, 0,
                       sizeof(USBPCAP_ADDRESS_FILTER));

                /*
                 * Set the reference count
                 *
                 * The reference count will drop down to zero once the
                 * roothub filter object gets destroyed.
                 */
                pDeviceData->pRootData->refCount = 1L;
            }
            else
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
            }
        }

        KeInitializeSpinLock(&pDeviceData->endpointTableSpinLock);
        pDeviceData->endpointTable = USBPcapInitializeEndpointTable(NULL);

        pDeviceData->descriptor = NULL;
    }
    else
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
    }

    pDevExt->context.usb.pDeviceData = pDeviceData;

    if (!NT_SUCCESS(status))
    {
        USBPcapFreeDeviceData(pDevExt);
    }
    else if (allocRoothubData == FALSE)
    {
        /* Set up parent and target objects in USBPCAP_DEVICE_DATA */
        pDeviceData->pParentFlt = pParentDevExt->pThisDevObj;
        pDeviceData->pNextParentFlt = pParentDevExt->pNextDevObj;
    }

    return status;
}
Example #14
0
File: pnp.c Project: kcrazy/winekit
NTSTATUS
Serenum_AddDevice(IN PDRIVER_OBJECT DriverObject,
                  IN PDEVICE_OBJECT BusPhysicalDeviceObject)
/*++
Routine Description.
    A bus has been found.  Attach our FDO to it.
    Allocate any required resources.  Set things up.  And be prepared for the
    first ``start device.''

Arguments:
    BusPhysicalDeviceObject - Device object representing the bus.  That to which
        we attach a new FDO.

    DriverObject - This very self referenced driver.

--*/
{
    NTSTATUS status;
    PDEVICE_OBJECT deviceObject;
    PFDO_DEVICE_DATA pDeviceData;
    HANDLE keyHandle;
    ULONG actualLength;

    PAGED_CODE();

    Serenum_KdPrint_Def(SER_DBG_PNP_TRACE, ("Add Device: 0x%x\n",
                                            BusPhysicalDeviceObject));
    //
    // Create our FDO
    //

    status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_DATA), NULL,
                            FILE_DEVICE_BUS_EXTENDER, 0, TRUE, &deviceObject);

    if (NT_SUCCESS(status)) {
        pDeviceData = (PFDO_DEVICE_DATA)deviceObject->DeviceExtension;
        RtlFillMemory (pDeviceData, sizeof (FDO_DEVICE_DATA), 0);

        pDeviceData->IsFDO = TRUE;
        pDeviceData->DebugLevel = SER_DEFAULT_DEBUG_OUTPUT_LEVEL;
        pDeviceData->Self = deviceObject;
        pDeviceData->AttachedPDO = NULL;
        pDeviceData->NumPDOs = 0;
        pDeviceData->DeviceState = PowerDeviceD0;
        pDeviceData->SystemState = PowerSystemWorking;
        pDeviceData->PDOForcedRemove = FALSE;

        pDeviceData->SystemWake=PowerSystemUnspecified;
        pDeviceData->DeviceWake=PowerDeviceUnspecified;

        pDeviceData->Removed = FALSE;

        //
        // Set the PDO for use with PlugPlay functions
        //

        pDeviceData->UnderlyingPDO = BusPhysicalDeviceObject;


        //
        // Attach our filter driver to the device stack.
        // the return value of IoAttachDeviceToDeviceStack is the top of the
        // attachment chain.  This is where all the IRPs should be routed.
        //
        // Our filter will send IRPs to the top of the stack and use the PDO
        // for all PlugPlay functions.
        //

        pDeviceData->TopOfStack
            = IoAttachDeviceToDeviceStack(deviceObject, BusPhysicalDeviceObject);

        if (!pDeviceData->TopOfStack) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoAttach failed (%x)", status));
            IoDeleteDevice(deviceObject);
            return STATUS_UNSUCCESSFUL;
        }

        //
        // Set the type of IO we do
        //

        if (pDeviceData->TopOfStack->Flags & DO_BUFFERED_IO) {
            deviceObject->Flags |= DO_BUFFERED_IO;
        } else if (pDeviceData->TopOfStack->Flags & DO_DIRECT_IO) {
            deviceObject->Flags |= DO_DIRECT_IO;
        }

        //
        // Bias outstanding request to 1 so that we can look for a
        // transition to zero when processing the remove device PlugPlay IRP.
        //

        pDeviceData->OutstandingIO = 1;

        KeInitializeEvent(&pDeviceData->RemoveEvent, SynchronizationEvent,
                          FALSE);
        KeInitializeSemaphore(&pDeviceData->CreateSemaphore, 1, 1);
        KeInitializeSpinLock(&pDeviceData->EnumerationLock);



        //
        // Tell the PlugPlay system that this device will need an interface
        // device class shingle.
        //
        // It may be that the driver cannot hang the shingle until it starts
        // the device itself, so that it can query some of its properties.
        // (Aka the shingles guid (or ref string) is based on the properties
        // of the device.)
        //

        status = IoRegisterDeviceInterface(BusPhysicalDeviceObject,
                                           (LPGUID)&GUID_SERENUM_BUS_ENUMERATOR,
                                           NULL,
                                           &pDeviceData->DevClassAssocName);

        if (!NT_SUCCESS(status)) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoRegisterDCA failed (%x)", status));
            IoDetachDevice(pDeviceData->TopOfStack);
            IoDeleteDevice(deviceObject);
            return status;
        }

        //
        // If for any reason you need to save values in a safe location that
        // clients of this DeviceClassAssociate might be interested in reading
        // here is the time to do so, with the function
        // IoOpenDeviceClassRegistryKey
        // the symbolic link name used is was returned in
        // pDeviceData->DevClassAssocName (the same name which is returned by
        // IoGetDeviceClassAssociations and the SetupAPI equivs.
        //

#if DBG
        {
            PWCHAR deviceName = NULL;
            ULONG nameLength = 0;

            status = IoGetDeviceProperty(BusPhysicalDeviceObject,
                                         DevicePropertyPhysicalDeviceObjectName, 0,
                                         NULL, &nameLength);

            if ((nameLength != 0) && (status == STATUS_BUFFER_TOO_SMALL)) {
                deviceName = ExAllocatePool(NonPagedPool, nameLength);

                if (NULL == deviceName) {
                    goto someDebugStuffExit;
                }

                IoGetDeviceProperty(BusPhysicalDeviceObject,
                                    DevicePropertyPhysicalDeviceObjectName,
                                    nameLength, deviceName, &nameLength);

                Serenum_KdPrint(pDeviceData, SER_DBG_PNP_TRACE,
                                ("AddDevice: %x to %x->%x (%ws) \n", deviceObject,
                                 pDeviceData->TopOfStack, BusPhysicalDeviceObject,
                                 deviceName));
            }

someDebugStuffExit:
            ;
            if (deviceName != NULL) {
                ExFreePool(deviceName);
            }
        }
#endif // DBG

        //
        // Turn on the shingle and point it to the given device object.
        //
        status = IoSetDeviceInterfaceState(&pDeviceData->DevClassAssocName,
                                           TRUE);

        if (!NT_SUCCESS(status)) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoSetDeviceClass failed (%x)", status));
            return status;
        }

        //
        // Open the registry and read in our settings
        //

        status = IoOpenDeviceRegistryKey(pDeviceData->UnderlyingPDO,
                                         PLUGPLAY_REGKEY_DEVICE,
                                         STANDARD_RIGHTS_READ, &keyHandle);

        if (status == STATUS_SUCCESS) {
            status
                = Serenum_GetRegistryKeyValue(keyHandle, L"SkipEnumerations",
                                              sizeof(L"SkipEnumerations"),
                                              &pDeviceData->SkipEnumerations,
                                              sizeof(pDeviceData->SkipEnumerations),
                                              &actualLength);

            if ((status != STATUS_SUCCESS)
                    || (actualLength != sizeof(pDeviceData->SkipEnumerations))) {
                pDeviceData->SkipEnumerations = 0;
                status = STATUS_SUCCESS;

            }

            ZwClose(keyHandle);
        }
    }

    if (NT_SUCCESS(status)) {
        deviceObject->Flags |= DO_POWER_PAGABLE;
        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    }

    return status;
}
Example #15
0
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
 * FUNCTION: Entry-point for the driver
 * ARGUMENTS:
 *     DriverObject: Our driver object
 *     RegistryPath: Unused
 * RETURNS:
 *     STATUS_SUCCESS on successful initialization of at least one drive
 *     STATUS_NO_SUCH_DEVICE if we didn't find even one drive
 *     STATUS_UNSUCCESSFUL otherwise
 */
{
    HANDLE ThreadHandle;

    UNREFERENCED_PARAMETER(RegistryPath);

    /*
     * Set up dispatch routines
     */
    DriverObject->MajorFunction[IRP_MJ_CREATE]         = (PDRIVER_DISPATCH)CreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = (PDRIVER_DISPATCH)CreateClose;
    DriverObject->MajorFunction[IRP_MJ_READ]           = (PDRIVER_DISPATCH)ReadWrite;
    DriverObject->MajorFunction[IRP_MJ_WRITE]          = (PDRIVER_DISPATCH)ReadWrite;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DeviceIoctl;

    DriverObject->DriverUnload = Unload;

    /*
     * We depend on some zeroes in these structures.  I know this is supposed to be
     * initialized to 0 by the complier but this makes me feel beter.
     */
    memset(&gControllerInfo, 0, sizeof(gControllerInfo));

    /*
     * Set up queue.  This routine cannot fail (trust me, I wrote it).
     */
    IoCsqInitialize(&Csq, CsqInsertIrp, CsqRemoveIrp, CsqPeekNextIrp,
                    CsqAcquireLock, CsqReleaseLock, CsqCompleteCanceledIrp);

    /*
     * ...and its lock
     */
    KeInitializeSpinLock(&IrpQueueLock);

    /*
     * ...and the queue list itself
     */
    InitializeListHead(&IrpQueue);

    /*
     * The queue is counted by a semaphore.  The queue management thread
     * blocks on this semaphore, so if requests come in faster than the queue
     * thread can handle them, the semaphore count goes up.
     */
    KeInitializeSemaphore(&QueueSemaphore, 0, 0x7fffffff);

    /*
     * Event to terminate that thread
     */
    KeInitializeEvent(&QueueThreadTerminate, NotificationEvent, FALSE);

    /*
     * Create the queue processing thread.  Save its handle in the global variable
     * ThreadHandle so we can wait on its termination during Unload.
     */
    if(PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "Unable to create system thread; failing init\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, *PsThreadType, KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "Unable to reference returned thread handle; failing init\n");
        return STATUS_UNSUCCESSFUL;
    }

    /*
     * Close the handle, now that we have the object pointer and a reference of our own.
     * The handle will certainly not be valid in the context of the caller next time we
     * need it, as handles are process-specific.
     */
    ZwClose(ThreadHandle);

    /*
     * Start the device discovery proces.  Returns STATUS_SUCCESS if
     * it finds even one drive attached to one controller.
     */
    if(!AddControllers(DriverObject))
        return STATUS_NO_SUCH_DEVICE;

    return STATUS_SUCCESS;
}
Example #16
0
BOOLEAN
RdsvrDatagramInit (
	PLFS_TABLE	LfsTable,
	PVOID		*DGSvrCtx,
	PVOID		*NtcCtx
	) 
{
	NTSTATUS			status;
	OBJECT_ATTRIBUTES	objectAttributes;

	//	create the datagram server thread

	LFSDGSvrCtx.LfsTable = LfsTable;
	*DGSvrCtx = &LFSDGSvrCtx;

	KeInitializeEvent( &LFSDGSvrCtx.ShutdownEvent, NotificationEvent, FALSE );
	KeInitializeEvent( &LFSDGSvrCtx.NetworkEvent, NotificationEvent, FALSE );
	KeInitializeEvent( &LFSDGSvrCtx.DatagramRecvEvent, NotificationEvent, FALSE );

	KeInitializeSpinLock( &LFSDGSvrCtx.RecvDGPktQSpinLock );
	InitializeListHead( &LFSDGSvrCtx.RecvDGPktQueue );

	InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

	status = PsCreateSystemThread( &LFSDGSvrCtx.hSvrThread,
								   THREAD_ALL_ACCESS,
								   &objectAttributes,
								   NULL,
								   NULL,
								   RedirDataGramSvrThreadProc,
								   &LFSDGSvrCtx );

	if (!NT_SUCCESS(status)) {

		NDAS_ASSERT( FALSE );
		return FALSE;
	}

	//	create the datagram notification broadcaster
	
	InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

	KeInitializeEvent( &LFSNtcCtx.ShutdownEvent, NotificationEvent, FALSE );

	LFSNtcCtx.LfsTable = LfsTable;
	*NtcCtx = &LFSNtcCtx;

	InitializeListHead( &LFSNtcCtx.SendPkts );

	status = PsCreateSystemThread( &LFSNtcCtx.hThread,
								   THREAD_ALL_ACCESS,
								   &objectAttributes,
								   NULL,
								   NULL,
								   RedirDataGramNotifierThreadProc,
								   &LFSNtcCtx );

	if (!NT_SUCCESS(status)) {

		NDAS_ASSERT( FALSE );
		return FALSE;
	}

	return TRUE;
}
Example #17
0
static NTSTATUS
FdoStartDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PFDO_DEVICE_EXTENSION DeviceExtension;
    PCM_RESOURCE_LIST AllocatedResources;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
    ULONG FoundBusNumber = FALSE;
    ULONG i;

    DPRINT("Called\n");

    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    AllocatedResources = IoGetCurrentIrpStackLocation(Irp)->Parameters.StartDevice.AllocatedResources;
    if (!AllocatedResources)
    {
        DPRINT("No allocated resources sent to driver\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    if (AllocatedResources->Count < 1)
    {
        DPRINT("Not enough allocated resources sent to driver\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    if (AllocatedResources->List[0].PartialResourceList.Version != 1 ||
        AllocatedResources->List[0].PartialResourceList.Revision != 1)
        return STATUS_REVISION_MISMATCH;

    ASSERT(DeviceExtension->State == dsStopped);

    /* By default, use the bus number in the resource list header */
    DeviceExtension->BusNumber = AllocatedResources->List[0].BusNumber;

    for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
    {
        ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
        switch (ResourceDescriptor->Type)
        {
            case CmResourceTypeBusNumber:
                if (FoundBusNumber || ResourceDescriptor->u.BusNumber.Length != 1)
                    return STATUS_INVALID_PARAMETER;

                /* Use this one instead */
                ASSERT(AllocatedResources->List[0].BusNumber == ResourceDescriptor->u.BusNumber.Start);
                DeviceExtension->BusNumber = ResourceDescriptor->u.BusNumber.Start;
                DPRINT("Found bus number resource: %lu\n", DeviceExtension->BusNumber);
                FoundBusNumber = TRUE;
                break;

            default:
                DPRINT("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
        }
    }

    InitializeListHead(&DeviceExtension->DeviceListHead);
    KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
    DeviceExtension->DeviceListCount = 0;
    DeviceExtension->State = dsStarted;

    ExInterlockedInsertTailList(
        &DriverExtension->BusListHead,
        &DeviceExtension->ListEntry,
        &DriverExtension->BusListLock);

  Irp->IoStatus.Information = 0;

  return STATUS_SUCCESS;
}
Example #18
0
NTSTATUS DriverEntry(
	IN  PDRIVER_OBJECT  driverObject,
	IN  PUNICODE_STRING registryPath)
{
	NTSTATUS status = STATUS_SUCCESS;
	NTSTATUS symbolicLinkCreationStatus = STATUS_SUCCESS;
	UNICODE_STRING deviceName;
	UNICODE_STRING dosDeviceName;
	HANDLE threadHandle;
	NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParams = {0};
	UNICODE_STRING defaultSDDLString;

#ifdef DEBUG
	DbgBreakPoint();
#endif

	status = drvCtlInit(driverObject);

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

	gDriverUnloading = FALSE;

	RtlInitUnicodeString(&defaultSDDLString, L"D:P(A;;GA;;;BU)");
	RtlInitUnicodeString(&deviceName, DEVICE_NAME);

	status = IoCreateDeviceSecure(
		driverObject, 
		0,
		&deviceName, 
		FILE_DEVICE_NETWORK, 
		0, 
		FALSE, 
		&defaultSDDLString,
		NULL,
		&gDeviceObject);

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

	RtlInitUnicodeString(&dosDeviceName, SYMBOLIC_LINK_NAME);

	status = IoCreateSymbolicLink(&dosDeviceName, &deviceName);
	symbolicLinkCreationStatus = status;

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

	status = FwpsInjectionHandleCreate0(
		AF_UNSPEC,
		FWPS_INJECTION_TYPE_STREAM,
		&gInjectionHandle);

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

	gNdisGenericObj = NdisAllocateGenericObject(
			driverObject, 
			TAG_NDIS_OBJ,
			0);

	if (gNdisGenericObj == NULL)
	{
		status = STATUS_NO_MEMORY;
		goto Exit;
	}

	nblPoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	nblPoolParams.Header.Revision = 
		NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
	nblPoolParams.Header.Size = 
		NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;

	nblPoolParams.fAllocateNetBuffer = TRUE;
	nblPoolParams.DataSize = 0;

	nblPoolParams.PoolTag = TAG_NBL_POOL;

	gNetBufferListPool = NdisAllocateNetBufferListPool(
                        gNdisGenericObj,
                        &nblPoolParams);

	if(gNetBufferListPool == NULL)
	{
		status = STATUS_NO_MEMORY;
		goto Exit;
	}

	InitializeListHead(&gPacketQueue);
	KeInitializeSpinLock(&gPacketQueueLock);  

	InitializeListHead(&flowContextList);
	KeInitializeSpinLock(&flowContextListLock);

	KeInitializeEvent(
		&gWorkerEvent,
		NotificationEvent,
		FALSE
	);
	
	status = RegisterCallouts(gDeviceObject);

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

	status = PsCreateSystemThread(
			&threadHandle,
			THREAD_ALL_ACCESS,
			NULL,
			NULL,
			NULL,
			thAnalyzer,
			NULL);

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

	status = ObReferenceObjectByHandle(
		threadHandle,
		0,
		NULL,
		KernelMode,
		(PVOID*) &gThreadObj,
		NULL);

	ASSERT(NT_SUCCESS(status));
	
	KeSetBasePriorityThread(
		(PKTHREAD) gThreadObj,
		-2);

	ZwClose(threadHandle);

	driverObject->DriverUnload = DriverUnload;

Exit:
   
	if (!NT_SUCCESS(status))
	{
		if (gFwpmEngineHandle != NULL)
		{
			UnregisterCallouts();
		}

		if (gInjectionHandle != NULL)
		{
			FwpsInjectionHandleDestroy0(gInjectionHandle);
		}

		if (gDeviceObject)
		{
			IoDeleteDevice(gDeviceObject);
		}

		if(NT_SUCCESS(symbolicLinkCreationStatus))
		{
			IoDeleteSymbolicLink(&dosDeviceName);
		}

		if (gNetBufferListPool != NULL)
		{
			NdisFreeNetBufferListPool(gNetBufferListPool);
		}
			
		if (gNdisGenericObj != NULL)
		{
			NdisFreeGenericObject(gNdisGenericObj);
		}
	}

return status;
}
VOID
PrimarySessionThreadProc (
	IN PPRIMARY_SESSION PrimarySession
	)
{
	BOOLEAN		primarySessionTerminate = FALSE;
	NTSTATUS	status;
	_U16		slotIndex;
	PLIST_ENTRY	primarySessionRequestEntry;


	ASSERT( SESSION_SLOT_COUNT == 1 );
	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	DebugTrace2( 0, Dbg2, ("PrimarySessionThreadProc: Start PrimarySession = %p\n", PrimarySession) );
	
	PrimarySession_Reference( PrimarySession );

	SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_INITIALIZING );
	
	InitializeListHead( &PrimarySession->Thread.OpenedFileQueue );
	KeInitializeSpinLock( &PrimarySession->Thread.OpenedFileQSpinLock );

	KeInitializeEvent( &PrimarySession->Thread.WorkCompletionEvent, NotificationEvent, FALSE );

	PrimarySession->SessionContext.SessionSlotCount = SESSION_SLOT_COUNT;

	for (slotIndex = 0; slotIndex < PrimarySession->SessionContext.SessionSlotCount; slotIndex ++) {

		PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_WAIT;
		PrimarySession->Thread.IdleSlotCount ++;
	}

	ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_INITIALIZING );
	SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_START );
	SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED );

	KeSetEvent( &PrimarySession->ReadyEvent, IO_DISK_INCREMENT, FALSE );

	status = LpxTdiRecvWithCompletionEvent( PrimarySession->ConnectionFileObject,
										    &PrimarySession->Thread.TdiReceiveContext,
										    (PUCHAR)&PrimarySession->Thread.NdfsRequestHeader,
										    sizeof(NDFS_REQUEST_HEADER),
										    0,
										    NULL,
										    NULL );

	if (NT_SUCCESS(status)) {

		PrimarySession->Thread.TdiReceiving = TRUE;
	
	} else {
	
		ASSERT( NDASFAT_BUG );
		SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
		primarySessionTerminate = TRUE;
	} 

	while (primarySessionTerminate == FALSE) {

		PKEVENT				events[3];
		LONG				eventCount;
		NTSTATUS			eventStatus;
		LARGE_INTEGER		timeOut;


		ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

		eventCount = 0;

		events[eventCount++] = &PrimarySession->RequestEvent;

		if (!FlagOn(PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING)) {

			events[eventCount++] = &PrimarySession->Thread.WorkCompletionEvent;

			if (FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN)) {
			
				if (PrimarySession->Thread.IdleSlotCount == PrimarySession->SessionContext.SessionSlotCount) {

					CloseOpenFiles( PrimarySession, TRUE );
				
					KeSetEvent( &PrimarySession->Thread.ShutdownPrimarySessionRequest->CompleteEvent, 
								IO_DISK_INCREMENT, 
								FALSE );

					SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT );
					ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN );
				}
			}	 
		
			if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT)) {

				if (PrimarySession->Thread.TdiReceiving == TRUE) {

					ASSERT( PrimarySession->Thread.IdleSlotCount != 0 );
					events[eventCount++] = &PrimarySession->Thread.TdiReceiveContext.CompletionEvent;
				}
			}

			ASSERT( eventCount <= THREAD_WAIT_OBJECTS );
		}

		timeOut.QuadPart = -5*HZ;
		eventStatus = KeWaitForMultipleObjects( eventCount, 
												events, 
												WaitAny, 
												Executive, 
												KernelMode,
												TRUE,
												&timeOut,
												NULL );

#if 0
		if (!FlagOn(PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING)) {

			if (eventStatus == STATUS_TIMEOUT || eventStatus == 2) {
			
				if (PrimarySession->Thread.SessionState == SESSION_TREE_CONNECT) {
				
					ASSERT( PrimarySession->NetdiskPartition );
				
					if (!(PrimarySession->NetdiskPartition->NetdiskVolume[NETDISK_PRIMARY].VolumeState == VolumeMounted || 
						  PrimarySession->NetdiskPartition->NetdiskVolume[NETDISK_SECONDARY2PRIMARY].VolumeState == VolumeMounted)) {

						DebugTrace2( 0, Dbg2,
									   ("Netdisk Volume is unmounted\n") );

						if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT))
							primarySessionTerminate = TRUE;
		
						continue;
					}
				}
			}
		}

#endif

		if (eventStatus == STATUS_TIMEOUT) {

			continue;
		}

		if (!NT_SUCCESS(eventStatus) || eventStatus >= eventCount) {

			NdasFatDbgBreakPoint();
			SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
			primarySessionTerminate = TRUE;
			continue;
		}
		
		KeClearEvent( events[eventStatus] );

		if (eventStatus == 0) {

			while (primarySessionRequestEntry = ExInterlockedRemoveHeadList( &PrimarySession->RequestQueue,
																			 &PrimarySession->RequestQSpinLock)) {

				PPRIMARY_SESSION_REQUEST	primarySessionRequest;
			
				primarySessionRequest = CONTAINING_RECORD( primarySessionRequestEntry,
														   PRIMARY_SESSION_REQUEST,
														   ListEntry );

				if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT ||
					primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT_AND_TERMINATE) {

					DebugTrace2( 0, Dbg2, 
								   ((primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT) ?
								   ("PRIMARY_SESSION_REQ_DISCONNECT: DisconnectFromSecondary\n") :
									("PRIMARY_SESSION_REQ_DISCONNECT_AND_TERMINATE: DisconnectFromSecondary\n")) );

					if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) {

						DisconnectFromSecondary( PrimarySession );
						ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED );
						SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );
					}

					if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT_AND_TERMINATE)
						primarySessionTerminate = TRUE;

					if (primarySessionRequest->Synchronous == TRUE)
						KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
					else
						DereferencePrimarySessionRequest( primarySessionRequest );

				} else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DOWN) {
					
					SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_STOPED );
					primarySessionTerminate = TRUE;

					if (primarySessionRequest->Synchronous == TRUE)
						KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
					else
						DereferencePrimarySessionRequest( primarySessionRequest );
				
				} else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_SHUTDOWN) {

					DebugTrace2( 0, Dbg, ("PrimarySessionThreadProc: PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN\n") );
					SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN );

					ASSERT (primarySessionRequest->Synchronous == TRUE);

					PrimarySession->Thread.ShutdownPrimarySessionRequest = primarySessionRequest;

					if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) {

						DisconnectFromSecondary( PrimarySession );
						ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED );
						SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );
					}

				} else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_STOPPING) {

					SetFlag( PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING );
					
					if (PrimarySession->IsLocalAddress == FALSE) {

						CloseOpenFiles( PrimarySession, FALSE );
					}

					if (primarySessionRequest->Synchronous == TRUE)
						KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
					else
						DereferencePrimarySessionRequest( primarySessionRequest );

				} else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_CANCEL_STOPPING) {

					ClearFlag( PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING );

					if (primarySessionRequest->Synchronous == TRUE)
						KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
					else
						DereferencePrimarySessionRequest( primarySessionRequest );

				} else {

					ASSERT( NDASFAT_BUG );
					SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
				}
			}

			continue;
		
		} else if (eventStatus == 1) {

			while (TRUE) {
	
				for (slotIndex = 0; slotIndex < PrimarySession->SessionContext.SessionSlotCount; slotIndex ++) {

					if (PrimarySession->Thread.SessionSlot[slotIndex].State == SLOT_FINISH)
						break;
				}

				if (slotIndex == PrimarySession->SessionContext.SessionSlotCount)
					break;
			
				PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_WAIT;
				PrimarySession->Thread.IdleSlotCount ++;

				if (PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_SUCCESS) {

					PNDFS_REPLY_HEADER		ndfsReplyHeader;

					ndfsReplyHeader = (PNDFS_REPLY_HEADER)PrimarySession->Thread.SessionSlot[slotIndex].ReplyMessageBuffer;
										
					PrimarySession->Thread.SessionSlot[slotIndex].Status
						= SendNdfsWinxpMessage( PrimarySession,
												ndfsReplyHeader,
												PrimarySession->Thread.SessionSlot[slotIndex].NdfsWinxpReplyHeader,
												PrimarySession->Thread.SessionSlot[slotIndex].ReplyDataSize,
												slotIndex );

				}
	
				if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool) {

					ExFreePool(PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool);	
					PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool = NULL;
					PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0;
				}
		
				if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool) {

					ExFreePool(PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool);	
					PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool = NULL;
					PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0;
				}

				if (!(PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_SUCCESS || 
					  PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_PENDING)) {

					SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );

#if 0
					if (PrimarySession->NetdiskPartition) {

						NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
															   PrimarySession,
															   PrimarySession->NetdiskPartition, 
															   PrimarySession->IsLocalAddress );

						PrimarySession->NetdiskPartition = NULL;
					}
#endif

					primarySessionTerminate = TRUE;
					break;		
				 }
				
				if (PrimarySession->Thread.SessionState == SESSION_CLOSED) {

#if 0
					if (PrimarySession->NetdiskPartition) {

						NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
															   PrimarySession,
															   PrimarySession->NetdiskPartition, 
															   PrimarySession->IsLocalAddress );
	
						PrimarySession->NetdiskPartition = NULL;
					}
#endif

					primarySessionTerminate = TRUE;
					break;		
				}

				if (PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_SUCCESS) {

					if (PrimarySession->Thread.TdiReceiving == FALSE) {

						status = LpxTdiRecvWithCompletionEvent( PrimarySession->ConnectionFileObject,
															    &PrimarySession->Thread.TdiReceiveContext,
															    (PUCHAR)&PrimarySession->Thread.NdfsRequestHeader,
															    sizeof(NDFS_REQUEST_HEADER),
															    0,
															    NULL,
															    NULL );

						if (!NT_SUCCESS(status)) {

							ASSERT( NDASFAT_BUG );

							SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
							primarySessionTerminate = TRUE;
							break;
						}
						
						PrimarySession->Thread.TdiReceiving = TRUE;
					}
				}
			}		
		
			continue;
		
		} else {

			ASSERT( eventStatus == 2 );  // Receive Event
			ASSERT( !FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT) &&
				    !FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN) );

			if (PrimarySession->Thread.TdiReceiveContext.Result != sizeof(NDFS_REQUEST_HEADER)) {

				DebugTrace2( 0, Dbg,
							   ("DispatchRequest: Disconnected, PrimarySession = Data received:%d\n",
							   PrimarySession->Thread.TdiReceiveContext.Result) );

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );
				primarySessionTerminate = TRUE;
				
				continue;		
			}

			PrimarySession->Thread.TdiReceiving = FALSE;

#if 0
			if (PrimarySession->NetdiskPartition) {

				PENABLED_NETDISK EnabledNetdisk = PrimarySession->NetdiskPartition->EnabledNetdisk;
				
				ASSERT( EnabledNetdisk );

				if (NetdiskManager_IsStoppedNetdisk(GlobalLfs.NetdiskManager, EnabledNetdisk)) {
				    
					DebugTrace2( 0, Dbg2,
								   ("PrimarySessionThread: %p Netdisk is stopped\n", PrimarySession) );

					DebugTrace2( 0, Dbg2, ("DispatchWinXpRequest: Netdisk is stopped.\n") );

					if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) { 
					
						// no other way to notify secondary about unmount without break backward compatability.
						
						DebugTrace2( 0, Dbg2, ("IsStoppedNetdisk: DisconnectFromSecondary\n") );
						DisconnectFromSecondary( PrimarySession );
						ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED );
						SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );
					}

					primarySessionTerminate = TRUE;
					continue;
				}
			} 

#endif

			status = DispatchRequest( PrimarySession );

			if (!(status == STATUS_SUCCESS || status == STATUS_PENDING)) {

				primarySessionTerminate = TRUE;
				continue;		
			}

			if (PrimarySession->Thread.SessionState == SESSION_CLOSED) {

				primarySessionTerminate = TRUE;
				continue;		
			}

			if (status == STATUS_SUCCESS) {

				if (PrimarySession->Thread.TdiReceiving == FALSE) {

					status = LpxTdiRecvWithCompletionEvent( PrimarySession->ConnectionFileObject,
														    &PrimarySession->Thread.TdiReceiveContext,
														    (PUCHAR)&PrimarySession->Thread.NdfsRequestHeader,
														    sizeof(NDFS_REQUEST_HEADER),
														    0,
														    NULL,
														    NULL );

					if (!NT_SUCCESS(status)) {

						SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
						primarySessionTerminate = TRUE;
					}

					PrimarySession->Thread.TdiReceiving = TRUE;
				}
			}
			
			continue;
		}
	}

	ExAcquireFastMutexUnsafe( &PrimarySession->FastMutex );
	SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_STOPED );
	ExReleaseFastMutexUnsafe( &PrimarySession->FastMutex );

	while (TRUE) {

		LARGE_INTEGER	timeOut;
		NTSTATUS		eventStatus;


		if (PrimarySession->Thread.IdleSlotCount == PrimarySession->SessionContext.SessionSlotCount)
			break;

		timeOut.QuadPart = -10*HZ;
		eventStatus = KeWaitForSingleObject( &PrimarySession->Thread.WorkCompletionEvent,
											 Executive,
											 KernelMode,
											 FALSE,
											 &timeOut );

		KeClearEvent( &PrimarySession->Thread.WorkCompletionEvent );

		if (eventStatus == STATUS_TIMEOUT) {

			ASSERT( NDASFAT_UNEXPECTED );
			continue;
		}

		while (TRUE) {
	
			for (slotIndex = 0; slotIndex < PrimarySession->SessionContext.SessionSlotCount; slotIndex++) {

				if (PrimarySession->Thread.SessionSlot[slotIndex].State == SLOT_FINISH)
					break;
			}

			if (slotIndex == PrimarySession->SessionContext.SessionSlotCount)
				break;

			DebugTrace2( 0, Dbg, ("PrimarySessionThreadProc: eventStatus = %d\n", eventStatus) );
			
			PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_WAIT;
			PrimarySession->Thread.IdleSlotCount++;

			if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool );	
				PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0;
			}
		
			if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool );	
				PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0;
			}
		}		
	}
	
	if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) {

		DebugTrace2( 0, Dbg2, ("PsTerminateSystemThread: DisconnectFromSecondary\n") );
		DisconnectFromSecondary( PrimarySession );
		ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED );
		SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );
	}

	CloseOpenFiles( PrimarySession, TRUE );

	while (primarySessionRequestEntry = ExInterlockedRemoveHeadList( &PrimarySession->RequestQueue,
																	 &PrimarySession->RequestQSpinLock)) {

		PPRIMARY_SESSION_REQUEST	primarySessionRequest;
			
		primarySessionRequest = CONTAINING_RECORD( primarySessionRequestEntry,
												   PRIMARY_SESSION_REQUEST,
												   ListEntry );

		if (primarySessionRequest->Synchronous == TRUE)
			KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
		else
			DereferencePrimarySessionRequest( primarySessionRequest );
	}

#if 0
	if (PrimarySession->NetdiskPartition) {

		NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager,
											   PrimarySession,
											   PrimarySession->NetdiskPartition, 
											   PrimarySession->IsLocalAddress );

		PrimarySession->NetdiskPartition = NULL;
	}
#endif

	DebugTrace2( 0, Dbg2,
				   ("PrimarySessionThreadProc: PsTerminateSystemThread PrimarySession = %p\n", 
				    PrimarySession) );

	SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_TERMINATED );

	PrimarySession_Dereference( PrimarySession );

	PsTerminateSystemThread( STATUS_SUCCESS );
}
Example #20
0
INIT_FUNCTION
VOID
NTAPI
HalpInitializePciBus(VOID)
{
#ifndef _MINIHAL_
    PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
    UCHAR PciType;
    PCI_SLOT_NUMBER PciSlot;
    ULONG i, j, k;
    UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH];
    PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer;
    PBUS_HANDLER BusHandler;
    ULONG HackFlags;
    BOOLEAN ExtendedAddressDecoding = FALSE;
    NTSTATUS Status;

    /* Query registry information */
    PciRegistryInfo = HalpQueryPciRegistryInfo();
    if (!PciRegistryInfo) return;

    /* Initialize the PCI configuration lock */
    KeInitializeSpinLock(&HalpPCIConfigLock);

    /* Get the type and free the info structure */
    PciType = PciRegistryInfo->HardwareMechanism & 0xF;

    /* Check if this is a type 2 PCI bus with at least one bus */
    if ((PciRegistryInfo->NoBuses) && (PciType == 2))
    {
        /* Setup the PCI slot */
        PciSlot.u.bits.Reserved = 0;
        PciSlot.u.bits.FunctionNumber = 0;

        /* Loop all slots */
        for (i = 0; i < 32; i++)
        {
            /* Try to setup a Type 2 PCI slot */
            PciType = 2;
            BusHandler = HalpAllocateAndInitPciBusHandler(2, 0, TRUE);
            if (!BusHandler) break;

            /* Now check if it's valid */
            if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break;

            /* Heh, the BIOS lied... try Type 1 */
            PciType = 1;
            BusHandler = HalpAllocateAndInitPciBusHandler(1, 0, TRUE);
            if (!BusHandler) break;

            /* Now check if it's valid */
            if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break;

            /* Keep trying */
            PciType = 2;
        }

        /* Now allocate the correct kind of handler */
        HalpAllocateAndInitPciBusHandler(PciType, 0, FALSE);
    }

    /* Okay, now loop all PCI bridges */
    do
    {
        /* Loop all PCI buses */
        for (i = 0; i < PciRegistryInfo->NoBuses; i++)
        {
            /* Check if we have a handler for it */
            if (!HalHandlerForBus(PCIBus, i))
            {
                /* Allocate it */
                HalpAllocateAndInitPciBusHandler(PciType, i, FALSE);
            }
        }
        /* Go to the next bridge */
    } while (HalpGetPciBridgeConfig(PciType, &PciRegistryInfo->NoBuses));

    /* Now build correct address range informaiton */
    HalpFixupPciSupportedRanges(PciRegistryInfo->NoBuses);

    /* Loop every bus */
    DbgPrint("\n====== PCI BUS HARDWARE DETECTION =======\n\n");
    PciSlot.u.bits.Reserved = 0;
    for (i = 0; i < PciRegistryInfo->NoBuses; i++)
    {
        /* Get the bus handler */
        BusHandler = HalHandlerForBus(PCIBus, i);

        /* Loop every device */
        for (j = 0; j < 32; j++)
        {
            /* Loop every function */
            PciSlot.u.bits.DeviceNumber = j;
            for (k = 0; k < 8; k++)
            {
                /* Build the final slot structure */
                PciSlot.u.bits.FunctionNumber = k;

                /* Read the configuration information */
                HalpReadPCIConfig(BusHandler,
                                  PciSlot,
                                  PciData,
                                  0,
                                  PCI_COMMON_HDR_LENGTH);

                /* Skip if this is an invalid function */
                if (PciData->VendorID == PCI_INVALID_VENDORID) continue;

                /* Print out the entry */
                HalpDebugPciDumpBus(i, j, k, PciData);

                /* Check if this is a Cardbus bridge */
                if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE)
                {
                    /* Not supported */
                    DbgPrint("\tDevice is a PCI Cardbus Bridge. It will not work!\n");
                    continue;
                }

                /* Check if this is a PCI device */
                if (PCI_CONFIGURATION_TYPE(PciData) != PCI_BRIDGE_TYPE)
                {
                    /* Check if it has an interrupt pin and line registered */
                    if ((PciData->u.type1.InterruptPin) &&
                        (PciData->u.type1.InterruptLine))
                    {
                        /* Check if this interrupt line is connected to the bus */
                        if (PciData->u.type1.InterruptLine < 16)
                        {
                            /* Is this an IDE device? */
                            if (!HalpIsIdeDevice(PciData))
                            {
                                /* We'll mask out this interrupt then */
                                DbgPrint("\tDevice is using IRQ %d! ISA Cards using that IRQ may fail!\n",
                                         PciData->u.type1.InterruptLine);
                                HalpPciIrqMask |= (1 << PciData->u.type1.InterruptLine);
                            }
                        }
                    }
                }

                /* Check for broken Intel chips */
                if (PciData->VendorID == 0x8086)
                {
                    /* Check for broken 82830 PCI controller */
                    if ((PciData->DeviceID == 0x04A3) &&
                        (PciData->RevisionID < 0x11))
                    {
                        /* Skip */
                        DbgPrint("\tDevice is a broken Intel 82430 PCI Controller. It will not work!\n\n");
                        continue;
                    }

                    /* Check for broken 82378 PCI-to-ISA Bridge */
                    if ((PciData->DeviceID == 0x0484) &&
                        (PciData->RevisionID <= 3))
                    {
                        /* Skip */
                        DbgPrint("\tDevice is a broken Intel 82378 PCI-to-ISA Bridge. It will not work!\n\n");
                        continue;
                    }

                    /* Check for broken 82450 PCI Bridge */
                    if ((PciData->DeviceID == 0x84C4) &&
                        (PciData->RevisionID <= 4))
                    {
                        DbgPrint("\tDevice is a Intel Orion 82450 PCI Bridge. It will not work!\n\n");
                        continue;
                    }
                }

                /* Do we know this card? */
                if (!ExtendedAddressDecoding)
                {
                    /* Check for it */
                    if (HalpIsRecognizedCard(PciRegistryInfo,
                                             PciData,
                                             HALP_CARD_FEATURE_FULL_DECODE))
                    {
                        /* We'll do chipset checks later */
                        DbgPrint("\tDevice has Extended Address Decoding. It may fail to work on older BIOSes!\n");
                        ExtendedAddressDecoding = TRUE;
                    }
                }

                /* Now check the registry for chipset hacks */
                Status = HalpGetChipHacks(PciData->VendorID,
                                          PciData->DeviceID,
                                          PciData->RevisionID,
                                          &HackFlags);
                if (NT_SUCCESS(Status))
                {
                    /* Check for broken ACPI routing */
                    if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_ACPI_IRQ_ROUTING)
                    {
                        DbgPrint("This chipset has broken ACPI IRQ Routing! Be aware!\n\n");
                        continue;
                    }

                    /* Check for broken ACPI timer */
                    if (HackFlags & HAL_PCI_CHIP_HACK_BROKEN_ACPI_TIMER)
                    {
                         DbgPrint("This chipset has a broken ACPI timer! Be aware!\n\n");
                         continue;
                    }

                    /* Check for hibernate-disable */
                    if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE)
                    {
                        DbgPrint("This chipset has a broken PCI device which is incompatible with hibernation. Be aware!\n\n");
                        continue;
                    }

                    /* Check for USB controllers that generate SMIs */
                    if (HackFlags & HAL_PCI_CHIP_HACK_USB_SMI_DISABLE)
                    {
                        DbgPrint("This chipset has a USB controller which generates SMIs. ReactOS will likely fail to boot!\n\n");
                        continue;
                    }
                }

                /* Terminate the entry */
                DbgPrint("\n");
            }
        }
    }

    /* Initialize NMI Crash Flag */
    HalpGetNMICrashFlag();

    /* Free the registry data */
    ExFreePoolWithTag(PciRegistryInfo, TAG_HAL);

    /* Tell PnP if this hard supports correct decoding */
    HalpMarkChipsetDecode(ExtendedAddressDecoding);
    DbgPrint("====== PCI BUS DETECTION COMPLETE =======\n\n");
#endif
}
Example #21
0
static NTSTATUS
V4vAddDevice(PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
{
    NTSTATUS          status = STATUS_SUCCESS;
    UNICODE_STRING    deviceName;
    PDEVICE_OBJECT    fdo = NULL;
    PXENV4V_EXTENSION pde = NULL;
    LONG              val;
    BOOLEAN           symlink = FALSE;
    LARGE_INTEGER     seed;
    WCHAR            *szSddl = NULL;
    UNICODE_STRING    sddlString;
    CHAR             *szFpath = NULL;

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    // We only allow one instance of this device type. If more than on pdo is created we need
    val = InterlockedCompareExchange(&g_deviceCreated, 1, 0);
    if (val != 0) {
        TraceWarning(("cannot instantiate more that one v4v device node.\n"));
        return STATUS_UNSUCCESSFUL;
    }

    do {
        // Create our device
        RtlInitUnicodeString(&deviceName, V4V_DEVICE_NAME);
        szSddl = g_win5Sddl;
        RtlInitUnicodeString(&sddlString, szSddl);

        status = 
            IoCreateDeviceSecure(driverObject,
                                 sizeof(XENV4V_EXTENSION),
                                 &deviceName,
                                 FILE_DEVICE_UNKNOWN,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &sddlString,
                                 (LPCGUID)&GUID_SD_XENV4V_CONTROL_OBJECT,
                                 &fdo);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create device object - error: 0x%x\n", status));
            fdo = NULL;
            break;
        }

        pde = (PXENV4V_EXTENSION)fdo->DeviceExtension;
        RtlZeroMemory(pde, sizeof(XENV4V_EXTENSION));
        RtlStringCchCopyW(pde->symbolicLinkText, XENV4V_SYM_NAME_LEN, V4V_SYMBOLIC_NAME);
        RtlInitUnicodeString(&pde->symbolicLink, pde->symbolicLinkText);

        // Create our symbolic link
        status = IoCreateSymbolicLink(&pde->symbolicLink, &deviceName);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create symbolic - error: 0x%x\n", status));
            break;
        }
        symlink = TRUE;       

        // Get our xenstore path
        szFpath = xenbus_find_frontend(pdo);
        if (szFpath == NULL) {
            status = STATUS_NO_SUCH_DEVICE;
            TraceError(("failed to locate XenStore front end path\n"));
            break;
        }

        // Setup the extension
        pde->magic = XENV4V_MAGIC;
        pde->pdo = pdo;
        pde->fdo = fdo;
        IoInitializeRemoveLock(&pde->removeLock, 'v4vx', 0, 0);
        pde->frontendPath = szFpath;
        szFpath = NULL;
        pde->state = XENV4V_DEV_STOPPED; // wait for start
        pde->lastPoState = PowerSystemWorking;
        pde->virqPort = null_EVTCHN_PORT();
        KeInitializeDpc(&pde->virqDpc, V4vVirqNotifyDpc, fdo);
        KeInitializeSpinLock(&pde->virqLock);
        KeInitializeSpinLock(&pde->dpcLock);
        KeInitializeTimerEx(&pde->timer, NotificationTimer);
        KeInitializeDpc(&pde->timerDpc,
                        V4vConnectTimerDpc,
                        fdo);
        KeInitializeSpinLock(&pde->timerLock);
        pde->timerCounter = 0;
        InitializeListHead(&pde->contextList);
        KeInitializeSpinLock(&pde->contextLock);
        pde->contextCount = 0;
        InitializeListHead(&pde->ringList);
        KeInitializeSpinLock(&pde->ringLock);
        InitializeListHead(&pde->pendingIrpQueue);
        pde->pendingIrpCount = 0;
        KeInitializeSpinLock(&pde->queueLock);
        IoCsqInitializeEx(&pde->csqObject,
                          V4vCsqInsertIrpEx,
                          V4vCsqRemoveIrp,
                          V4vCsqPeekNextIrp,
                          V4vCsqAcquireLock,
                          V4vCsqReleaseLock,
                          V4vCsqCompleteCanceledIrp);
        InitializeListHead(&pde->destList);
        pde->destCount = 0;
        ExInitializeNPagedLookasideList(&pde->destLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(XENV4V_DESTINATION),
                                        XENV4V_TAG,
                                        0);
        KeQueryTickCount(&seed);
        pde->seed = seed.u.LowPart;

        // Now attach us to the stack
        pde->ldo = IoAttachDeviceToDeviceStack(fdo, pdo);
        if (pde->ldo == NULL) {
            TraceError(("failed to attach device to stack - error: 0x%x\n", status));
            status = STATUS_NO_SUCH_DEVICE;
            break;
        }

        // Use direct IO and let the IO manager directly map user buffers; clear the init flag
        fdo->Flags |= DO_DIRECT_IO;
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;        

        // Made it here, go to connected state to be consistent
        xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CONNECTED);
    } while (FALSE);

    if (!NT_SUCCESS(status)) {
        if (fdo != NULL) {         
            if ((pde != NULL)&&(pde->ldo != NULL)) {
                IoDetachDevice(pde->ldo);
            }
            if (szFpath != NULL) {
                XmFreeMemory(szFpath);
            }
            if (symlink) {
                IoDeleteSymbolicLink(&pde->symbolicLink);
            }
            IoDeleteDevice(fdo);
        }
    }

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));

    return status;
}
Example #22
0
// Note:
// VStreamMask = 0x1 is reserved for kernel mode driver, UMX should not use it
// ref: SORA_RESET_RADIO_PHY_RX_INFO_BASE()
VOID SoraInitVStreamMan(__PRX_QUEUE_MANAGER RxMan)
{
    RxMan->VStreamFreeBitmap = 0xFFFFFFFF; //all free, lowest bit for kernel mode driver.
    KeInitializeSpinLock(&RxMan->VStreamFreeBitmapLock);
}
Example #23
0
BOOLEAN NTAPI
IntVideoPortSetupInterrupt(
   IN PDEVICE_OBJECT DeviceObject,
   IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
   IN PVIDEO_PORT_CONFIG_INFO ConfigInfo)
{
   NTSTATUS Status;
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;

   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

   /*
    * MSDN documentation for VIDEO_PORT_CONFIG_INFO states: "If a miniport driver's
    * HwVidFindAdapter function finds that the video adapter does not generate
    * interrupts or that it cannot determine a valid interrupt vector/level for
    * the adapter, HwVidFindAdapter should set both BusInterruptVector and
    * BusInterruptLevel to zero.
    */

   if (DriverExtension->InitializationData.HwInterrupt != NULL &&
       (ConfigInfo->BusInterruptLevel != 0 ||
       ConfigInfo->BusInterruptVector != 0))
   {
      ULONG InterruptVector;
      KIRQL Irql;
      KAFFINITY Affinity;

      InterruptVector = HalGetInterruptVector(
         ConfigInfo->AdapterInterfaceType,
         ConfigInfo->SystemIoBusNumber,
         ConfigInfo->BusInterruptLevel,
         ConfigInfo->BusInterruptVector,
         &Irql,
         &Affinity);

      if (InterruptVector == 0)
      {
         WARN_(VIDEOPRT, "HalGetInterruptVector failed\n");
         return FALSE;
      }

      KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
      Status = IoConnectInterrupt(
         &DeviceExtension->InterruptObject,
         IntVideoPortInterruptRoutine,
         DeviceExtension,
         &DeviceExtension->InterruptSpinLock,
         InterruptVector,
         Irql,
         Irql,
         ConfigInfo->InterruptMode,
         DeviceExtension->InterruptShared,
         Affinity,
         FALSE);

      if (!NT_SUCCESS(Status))
      {
         WARN_(VIDEOPRT, "IoConnectInterrupt failed with status 0x%08x\n", Status);
         return FALSE;
      }
   }

   return TRUE;
}
Example #24
0
NTSTATUS
DriverEntry(
__in PDRIVER_OBJECT  pDrvObj,
__in PUNICODE_STRING pRegistryPath
)
{
    NTSTATUS                       status = STATUS_SUCCESS;
#ifdef USE_STORPORT
    VIRTUAL_HW_INITIALIZATION_DATA hwInitData = { 0 };
#endif
#ifdef USE_SCSIPORT
    HW_INITIALIZATION_DATA         hwInitData = { 0 };
#endif
    pMPDriverInfo                  pMPDrvInfo;
    LARGE_INTEGER                  liTickCount;

    KdPrint2(("PhDskMnt::DriverEntry: Begin.\n"));

#ifdef MP_DrvInfo_Inline

    // Because there's no good way to clean up the allocation of the global driver information, 
    // the global information is kept in an inline structure.

    pMPDrvInfo = &lclDriverInfo;

#else

    //
    // Allocate basic miniport driver object (shared across instances of miniport). The pointer is kept in the driver binary's static storage.
    //
    // Because there's no good way to clean up the allocation of the global driver information, 
    // the global information will be leaked.  This is deemed acceptable since it's not expected
    // that DriverEntry will be invoked often in the life of a Windows boot.
    //

    pMPDrvInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(MPDriverInfo), MP_TAG_GENERAL);

    if (!pMPDrvInfo) {                                // No good?
        status = STATUS_INSUFFICIENT_RESOURCES;

        goto Done;
    }

#endif

    // Initialize driver globals structure

    pMPDrvInfoGlobal = pMPDrvInfo;                    // Save pointer in binary's storage.

    RtlZeroMemory(pMPDrvInfo, sizeof(MPDriverInfo));  // Set pMPDrvInfo's storage to a known state.

    pMPDrvInfo->pDriverObj = pDrvObj;                 // Save pointer to driver object.

    KeInitializeSpinLock(&pMPDrvInfo->DrvInfoLock);   // Initialize spin lock.

    InitializeListHead(&pMPDrvInfo->ListMPHBAObj);    // Initialize list head.

    KeQueryTickCount(&liTickCount);
    pMPDrvInfo->RandomSeed = liTickCount.LowPart;     // Initialize random seed.

    // Get registry parameters.

    MpQueryRegParameters(pRegistryPath, &pMPDrvInfo->MPRegInfo);

    // Set up information for ScsiPortInitialize().

#ifdef USE_STORPORT
    hwInitData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
#endif
#ifdef USE_SCSIPORT
#if NT4_COMPATIBLE
    hwInitData.HwInitializationDataSize = FIELD_OFFSET(HW_INITIALIZATION_DATA, HwAdapterControl);
#else
    hwInitData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
#endif
#endif

    hwInitData.HwInitialize = MpHwInitialize;           // Required for all ports.
    hwInitData.HwStartIo = MpHwStartIo;              // Required for all ports.
    hwInitData.HwFindAdapter = MpHwFindAdapter;          // Required for all ports.
    hwInitData.HwResetBus = MpHwResetBus;             // Required for all ports.
#ifndef NT4_COMPATIBLE
    hwInitData.HwAdapterControl = MpHwAdapterControl;       // Required for all post NT4 ports.
#endif
#ifdef USE_STORPORT
    hwInitData.HwFreeAdapterResources = MpHwFreeAdapterResources; // Required for virtual StorPort.
#endif

    hwInitData.AutoRequestSense = TRUE;
    hwInitData.TaggedQueuing = TRUE;
    hwInitData.MultipleRequestPerLu = TRUE;

    hwInitData.MapBuffers = STORAGE_MAP_BUFFERS_SETTING;

    hwInitData.DeviceExtensionSize = sizeof(HW_HBA_EXT);
    hwInitData.SpecificLuExtensionSize = sizeof(PVOID);
    hwInitData.SrbExtensionSize = sizeof(HW_SRB_EXTENSION);

    hwInitData.AdapterInterfaceType = STORAGE_INTERFACE_TYPE;

    status = StoragePortInitialize(                     // Tell port driver we're here.
        pDrvObj,
        pRegistryPath,
        (PHW_INITIALIZATION_DATA)&hwInitData,
        NULL
        );

    DbgPrint("PhDskMnt::DriverEntry: StoragePortInitialize returned 0x%X\n", status);

    if (NT_SUCCESS(status))
    {
        // Register our own dispatch hooks

        pMPDrvInfo->pChainUnload = pDrvObj->DriverUnload;
        pDrvObj->DriverUnload = ImScsiUnload;
    }
    else
    {
        ImScsiFreeGlobalResources();
    }

    KdPrint2(("PhDskMnt::DriverEntry: End. status=0x%X\n", status));

    return status;
}                                                     // End DriverEntry().
Example #25
0
BOOLEAN
ExpInitSystemPhase0 (
    VOID
    )

/*++

Routine Description:

    This function performs Phase 0 initialization of the executive component
    of the NT system.

Arguments:

    None.

Return Value:

    A value of TRUE is returned if the initialization is success. Otherwise
    a value of FALSE is returned.

--*/

{

    ULONG Index;
    BOOLEAN Initialized = TRUE;
    PGENERAL_LOOKASIDE Lookaside;

    //
    // Initialize Resource objects, currently required during SE
    // Phase 0 initialization.
    //

    if (ExpResourceInitialization() == FALSE) {
        Initialized = FALSE;
        KdPrint(("Executive: Resource initialization failed\n"));
    }

    //
    // Initialize query/set environment variable synchronization fast
    // mutex.
    //

    ExInitializeFastMutex(&ExpEnvironmentLock);

    //
    // Initialize the key manipulation resource.
    //

    ExInitializeResourceLite(&ExpKeyManipLock);

    //
    // Initialize the paged and nonpaged small pool lookaside structures,
    //

    InitializeListHead(&ExPoolLookasideListHead);
    for (Index = 0; Index < POOL_SMALL_LISTS; Index += 1) {
        Lookaside = &ExpSmallNPagedPoolLookasideLists[Index];
        ExInitializeSystemLookasideList(Lookaside,
                                        NonPagedPool,
                                        (Index + 1) * sizeof (POOL_BLOCK),
                                        'looP',
                                        256,
                                        &ExPoolLookasideListHead);

        Lookaside = &ExpSmallPagedPoolLookasideLists[Index];
        ExInitializeSystemLookasideList(Lookaside,
                                        PagedPool,
                                        (Index + 1) * sizeof (POOL_BLOCK),
                                        'looP',
                                        256,
                                        &ExPoolLookasideListHead);
    }

    //
    // Initialize the nonpaged and paged system lookaside lists.
    //

    InitializeListHead(&ExNPagedLookasideListHead);
    KeInitializeSpinLock(&ExNPagedLookasideLock);
    InitializeListHead(&ExPagedLookasideListHead);
    KeInitializeSpinLock(&ExPagedLookasideLock);

    //
    // Initialize the system paged and nonpaged lookaside list.
    //

    InitializeListHead(&ExSystemLookasideListHead);

    //
    // Initialize the Firmware table provider list
    //
    InitializeListHead(&ExpFirmwareTableProviderListHead);

    //
    // Initialize the FirmwareTableProvider resource
    //
    ExInitializeResourceLite(&ExpFirmwareTableResource);
    
    return ExpSystemOK(2, Initialized);
}
Example #26
0
ULONG
MpHwFindAdapter(
__in       PVOID                           DeviceExtension,
__in       PVOID                           pReservedArg1,
__in       PVOID                           pReservedArg2,
#ifdef USE_STORPORT
__in       PVOID                           pReservedArg3,
#endif
__in       PCHAR                           ArgumentString,
__in __out PPORT_CONFIGURATION_INFORMATION pConfigInfo,
__out      PBOOLEAN                        pBAgain
)
{
    ULONG              i,
        len,
        status = SP_RETURN_FOUND;
    PCHAR              pChar;
    pHW_HBA_EXT        pHBAExt = (pHW_HBA_EXT)DeviceExtension;
    NTSTATUS           ntstatus;

#if defined(_AMD64_)

    KLOCK_QUEUE_HANDLE LockHandle;

#else

    KIRQL              SaveIrql;

#endif

    UNREFERENCED_PARAMETER(pReservedArg1);
    UNREFERENCED_PARAMETER(pReservedArg2);
#ifdef USE_STORPORT
    UNREFERENCED_PARAMETER(pReservedArg3);
#endif
    UNREFERENCED_PARAMETER(ArgumentString);

    KdPrint(("PhDskMnt::MpHwFindAdapter:  Arg=%s%s%s, pHBAExt = 0x%p, pConfigInfo = 0x%p, IRQL=%i\n",
        ArgumentString != NULL ? "\"" : "(",
        ArgumentString != NULL ? ArgumentString : "null",
        ArgumentString != NULL ? "\"" : ")",
        pHBAExt,
        pConfigInfo,
        KeGetCurrentIrql()));

#if VERBOSE_DEBUG_TRACE > 0

    if (!KD_DEBUGGER_NOT_PRESENT)
        DbgBreakPoint();

#endif

    if (pMPDrvInfoGlobal->GlobalsInitialized)
    {
        LARGE_INTEGER wait_time;

        DbgPrint("PhDskMnt::MpHwFindAdapter: Already initialized.\n");

        wait_time.QuadPart = -1000000;
        KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
    }

    KeInitializeSpinLock(&pHBAExt->LUListLock);
    InitializeListHead(&pHBAExt->LUList);

    pHBAExt->HostTargetId = (UCHAR)pMPDrvInfoGlobal->MPRegInfo.InitiatorID;

    pConfigInfo->WmiDataProvider = FALSE;                       // Indicate WMI provider.

    pConfigInfo->NumberOfPhysicalBreaks = 4096;

    pConfigInfo->MaximumTransferLength = 8 << 20;                     // 8 MB.

#ifdef USE_STORPORT

    pConfigInfo->VirtualDevice = TRUE;                        // Inidicate no real hardware.
    pConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;

    if (pConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED)
        pConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_FULL64BIT_SUPPORTED;

#endif
#ifdef USE_SCSIPORT

    //if (pConfigInfo->NumberOfPhysicalBreaks == SP_UNINITIALIZED_VALUE)
    //    pConfigInfo->NumberOfPhysicalBreaks     = 4096;

    //if (pConfigInfo->MaximumTransferLength > (64 << 10))
    //    pConfigInfo->MaximumTransferLength      = 64 << 10;                     // 64 KB.

    pConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED;

#endif

    pConfigInfo->AlignmentMask = 0x3;                         // Indicate DWORD alignment.
    pConfigInfo->CachesData = FALSE;                       // Indicate miniport wants flush and shutdown notification.
    pConfigInfo->MaximumNumberOfTargets = SCSI_MAXIMUM_TARGETS;        // Indicate maximum targets.
    pConfigInfo->NumberOfBuses =
        (UCHAR)pMPDrvInfoGlobal->MPRegInfo.NumberOfBuses;                     // Indicate number of busses.
    pConfigInfo->ScatterGather = TRUE;                        // Indicate scatter-gather (explicit setting needed for Win2003 at least).
    pConfigInfo->AutoRequestSense = TRUE;
    pConfigInfo->TaggedQueuing = TRUE;
    pConfigInfo->MultipleRequestPerLu = TRUE;

    // Save Vendor Id, Product Id, Revision in device extension.

    pChar = (PCHAR)pMPDrvInfoGlobal->MPRegInfo.VendorId.Buffer;
    len = min(8, (pMPDrvInfoGlobal->MPRegInfo.VendorId.Length / 2));
    for (i = 0; i < len; i++, pChar += 2)
        pHBAExt->VendorId[i] = *pChar;

    pChar = (PCHAR)pMPDrvInfoGlobal->MPRegInfo.ProductId.Buffer;
    len = min(16, (pMPDrvInfoGlobal->MPRegInfo.ProductId.Length / 2));
    for (i = 0; i < len; i++, pChar += 2)
        pHBAExt->ProductId[i] = *pChar;

    pChar = (PCHAR)pMPDrvInfoGlobal->MPRegInfo.ProductRevision.Buffer;
    len = min(4, (pMPDrvInfoGlobal->MPRegInfo.ProductRevision.Length / 2));
    for (i = 0; i < len; i++, pChar += 2)
        pHBAExt->ProductRevision[i] = *pChar;

    // Add HBA extension to master driver object's linked list.

#if defined(_AMD64_)

    KeAcquireInStackQueuedSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, &LockHandle);

#else

    KeAcquireSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, &SaveIrql);

#endif

    InsertTailList(&pMPDrvInfoGlobal->ListMPHBAObj, &pHBAExt->List);

    pMPDrvInfoGlobal->DrvInfoNbrMPHBAObj++;

#if defined(_AMD64_)

    KeReleaseInStackQueuedSpinLock(&LockHandle);

#else

    KeReleaseSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, SaveIrql);

#endif

    if (!pMPDrvInfoGlobal->GlobalsInitialized)
    {
        HANDLE thread_handle;
        OBJECT_ATTRIBUTES object_attributes;

        KeInitializeSpinLock(&pMPDrvInfoGlobal->RequestListLock);
        InitializeListHead(&pMPDrvInfoGlobal->RequestList);
        KeInitializeEvent(&pMPDrvInfoGlobal->RequestEvent, SynchronizationEvent, FALSE);

#ifdef USE_SCSIPORT
        KeInitializeSpinLock(&pMPDrvInfoGlobal->ResponseListLock);
        KeInitializeEvent(&pMPDrvInfoGlobal->ResponseEvent, SynchronizationEvent, FALSE);
        InitializeListHead(&pMPDrvInfoGlobal->ResponseList);
#endif

        KeInitializeEvent(&pMPDrvInfoGlobal->StopWorker, NotificationEvent, FALSE);

        pMPDrvInfoGlobal->GlobalsInitialized = TRUE;

        InitializeObjectAttributes(&object_attributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

        ntstatus = PsCreateSystemThread(
            &thread_handle,
            (ACCESS_MASK)0L,
            &object_attributes,
            NULL,
            NULL,
            ImScsiWorkerThread,
            NULL);

        if (!NT_SUCCESS(ntstatus))
        {
            DbgPrint("PhDskMnt::ScsiGetLUExtension: Cannot create worker thread. (%#x)\n", ntstatus);

            status = SP_RETURN_ERROR;
        }
        else
        {
            ntstatus = ObReferenceObjectByHandle(
                thread_handle,
                FILE_READ_ATTRIBUTES | SYNCHRONIZE,
                *PsThreadType,
                KernelMode,
                (PVOID*)&pMPDrvInfoGlobal->WorkerThread,
                NULL
                );

            if (!NT_SUCCESS(ntstatus))
            {
                DbgPrint("PhDskMnt::ScsiGetLUExtension: Cannot reference worker thread. (%#x)\n", ntstatus);
                KeSetEvent(&pMPDrvInfoGlobal->StopWorker, (KPRIORITY)0, FALSE);
                ZwWaitForSingleObject(thread_handle, FALSE, NULL);

                status = SP_RETURN_ERROR;
            }

            ZwClose(thread_handle);
        }
    }

    //Done:
    *pBAgain = FALSE;

    KdPrint(("PhDskMnt::MpHwFindAdapter: End, status = 0x%X\n", status));

    return status;
}                                                     // End MpHwFindAdapter().
Example #27
0
PIOV_REQUEST_PACKET
FASTCALL
IovpTrackingDataCreateAndLock(
    IN PIRP           Irp
    )
/*++

  Description:

    This routine creates a tracking packet for a new IRP. The IRP does not get
    an initial reference count however. IovpTrackingDataReleaseLock must be
    called to drop the lock.

  Arguments:

    Irp                    - Irp to begin tracking.

  Return Value:

    iovPacket block, NULL if no memory.

--*/
{
    KIRQL oldIrql;
    PIOV_REQUEST_PACKET iovPacket;
    PLIST_ENTRY hashHead;
    ULONG trackingDataSize;
    LONG newCount;

    ExAcquireSpinLock( &IovpIrpHashLock, &oldIrql );

    iovPacket = IovpTrackingDataFindPointer(Irp, &hashHead) ;

    ASSERT(!iovPacket) ;

    //
    // One extra stack location is allocated as the "zero'th" is used to
    // simplify some logic...
    //
    trackingDataSize = sizeof(IOV_REQUEST_PACKET)+Irp->StackCount*sizeof(IOV_STACK_LOCATION) ;

    iovPacket = ExAllocatePoolWithTag(
        NonPagedPool,
        trackingDataSize,
        POOL_TAG_TRACKING_DATA
        );

    if (!iovPacket) {

        ExReleaseSpinLock( &IovpIrpHashLock, oldIrql );
        return iovPacket;
    }

    //RtlZeroMemory(iovPacket, trackingDataSize) ;

    //
    // From top to bottom, initialize the fields. Note that there is not a
    // "surrogateHead". If any code needs to find out the first entry in the
    // circularly linked list of IRPs (the first is the only non-surrogate IRP),
    // then HeadPacket should be used. Note that the link to the session is
    // stored by the headPacket, more on this later.
    //
    iovPacket->TrackedIrp = Irp;
    KeInitializeSpinLock( &iovPacket->IrpLock );
    iovPacket->ReferenceCount = 1;
    iovPacket->PointerCount = 0;
    iovPacket->Flags = 0;
    InitializeListHead(&iovPacket->HashLink);
    InitializeListHead(&iovPacket->SurrogateLink);
    InitializeListHead(&iovPacket->SessionHead);
    iovPacket->HeadPacket = iovPacket;
    iovPacket->StackCount = Irp->StackCount;
    iovPacket->AssertFlags = IovpTrackingFlags;
    iovPacket->RealIrpCompletionRoutine = NULL;
    iovPacket->RealIrpControl = 0;
    iovPacket->RealIrpContext = NULL;
    iovPacket->TopStackLocation = 0;
    iovPacket->PriorityBoost = 0;
    iovPacket->LastLocation = 0;
    iovPacket->RefTrackingCount =0;
    iovPacket->RestoreHandle = NULL;
    iovPacket->pIovSessionData = NULL;

    //
    // Place into hash table under lock (with the initial reference count)
    //
    InsertHeadList(hashHead, &iovPacket->HashLink);

    ExReleaseSpinLock( &IovpIrpHashLock, oldIrql );

    ExAcquireSpinLock( &iovPacket->IrpLock, &iovPacket->CallerIrql );

    newCount = InterlockedDecrement(&iovPacket->ReferenceCount);

    //
    // If this assert gets hit it means somebody got hold of tracking data
    // at a very odd (and probably buggy) time. Actually, this might happen
    // if an IRP was cancelled right as it entered IoCallDriver...
    //
    //ASSERT(newCount == 0);

    TRACKIRP_DBGPRINT((
        "  VRP CREATE(%x)->%x\n",
        Irp,
        iovPacket
        ), 3) ;

    return iovPacket ;
}
Example #28
0
BOOLEAN
PoInitSystem(
    IN ULONG  Phase
    )

/*++

Routine Description:

    This routine initializes the Power Manager.

Arguments:

    None

Return Value:

    The function value is a BOOLEAN indicating whether or not the Power Manager
    was successfully initialized.

--*/

{
    if (Phase == 0) {
        //
        // Initialize the Power manager database resource, lock, and the
        // queue headers.
        //

        KeInitializeSpinLock (&PopStateLock);
        InitializeListHead (&PopDeviceList);
        InitializeListHead (&PopAsyncStateChangeQueue);
        InitializeListHead (&PopSyncStateChangeQueue);
        InitializeListHead (&PopStateChangeInProgress);
        InitializeListHead (&PopStateChangeWorkerList);
        KeInitializeEvent  (&PopStateDatabaseIdle, SynchronizationEvent, TRUE);
        ExInitializeWorkItem (&PopStateChangeWorkItem, PopStateChangeWorker, NULL);

        KeInitializeTimer  (&PopStateChangeTimer);
        KeInitializeDpc (&PopStateChangeDpc, PopStateChange, NULL);
        PopStateChangeDpcActive = FALSE;
        PopSyncChangeInProgress = FALSE;

        //
        // idle.c
        //

        InitializeListHead (&PopActiveIdleScanQueue);

        KeInitializeTimer (&PopIdleScanTimer);
        KeInitializeDpc (&PopIdleScanDpc, PopScanForIdleDevices, NULL);

        // bugbug
        PopIdleScanTime.QuadPart = -50000000;

        //
        // Compute scan time in seconds
        //
        PopIdleScanTimeInSeconds = (ULONG) (PopIdleScanTime.QuadPart / -10000000);
    }

    if (Phase == 1) {

        //
        // Set PowerSequence value for suspend/hibernate support
        //

        PoPowerSequence = 1;

        //
        // Enable PowerManagement
        //

        PoSetPowerManagementEnable (TRUE);
    }

    //
    // Success
    //

    return TRUE;
}
Example #29
0
PPRIMARY_SESSION
PrimarySession_Create (
	IN  PIRP_CONTEXT			IrpContext,  
	IN	PVOLUME_DEVICE_OBJECT	VolDo,		 
	IN  PSESSION_INFORMATION	SessionInformation,
	IN  PIRP					Irp
	)
{
	PPRIMARY_SESSION	primarySession;
 	OBJECT_ATTRIBUTES	objectAttributes;
	NTSTATUS			status;
	LARGE_INTEGER		timeOut;

		
	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	VolDo_Reference( VolDo );

	primarySession = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY_SESSION), NDASNTFS_ALLOC_TAG );
	
	if (primarySession == NULL) {

		ASSERT( NDASNTFS_INSUFFICIENT_RESOURCES );
		VolDo_Dereference( VolDo );
		return NULL;
	}

	try {
	
		RtlZeroMemory( primarySession, sizeof(PRIMARY_SESSION) );

		primarySession->Flags = PRIMARY_SESSION_FLAG_INITIALIZING;

		primarySession->ReferenceCount = 1;
		primarySession->VolDo = VolDo;
		
		ExInitializeFastMutex( &primarySession->FastMutex )
		
		InitializeListHead( &primarySession->ListEntry );

		primarySession->NetdiskPartitionInformation = SessionInformation->NetdiskPartitionInformation;
	
		RtlInitEmptyUnicodeString( &primarySession->NetdiskPartitionInformation.VolumeName,
								   primarySession->NetdiskPartitionInformation.VolumeNameBuffer,
								   sizeof(primarySession->NetdiskPartitionInformation.VolumeNameBuffer) );

		if (RtlAppendUnicodeStringToString( &primarySession->NetdiskPartitionInformation.VolumeName,
											&SessionInformation->NetdiskPartitionInformation.VolumeName) != STATUS_SUCCESS) {

			ASSERT( NDASNTFS_UNEXPECTED );
		}

		ASSERT( primarySession->NetdiskPartitionInformation.VolumeName.Buffer == primarySession->NetdiskPartitionInformation.VolumeNameBuffer );

		primarySession->ConnectionFileHandle		= SessionInformation->ConnectionFileHandle;
		primarySession->ConnectionFileObject		= SessionInformation->ConnectionFileObject;

		primarySession->RemoteAddress				= SessionInformation->RemoteAddress;
		primarySession->IsLocalAddress				= SessionInformation->IsLocalAddress;

		primarySession->Irp									= Irp;

		primarySession->SessionContext = SessionInformation->SessionContext;

		primarySession->SessionContext.PrimaryMaxDataSize	= DEFAULT_NDAS_MAX_DATA_SIZE; //SessionInformation->PrimaryMaxDataSize;
		primarySession->SessionContext.SecondaryMaxDataSize	= DEFAULT_NDAS_MAX_DATA_SIZE; // SessionInformation->SecondaryMaxDataSize;

		DebugTrace( 0, Dbg2, ("primarySession->ConnectionFileHandle = %x " 
							   "primarySession->SessionContext.PrimaryMaxDataSize = %x primarySession->SessionContext.SecondaryMaxDataSize = %x\n", 
							    primarySession->ConnectionFileHandle, primarySession->SessionContext.PrimaryMaxDataSize, primarySession->SessionContext.SecondaryMaxDataSize) );

		KeInitializeEvent( &primarySession->ReadyEvent, NotificationEvent, FALSE );
	
		InitializeListHead( &primarySession->RequestQueue );
		KeInitializeSpinLock( &primarySession->RequestQSpinLock );
		KeInitializeEvent( &primarySession->RequestEvent, NotificationEvent, FALSE );

		primarySession->ThreadHandle = 0;
		primarySession->ThreadObject = NULL;

		primarySession->Thread.TdiReceiveContext.Irp = NULL;
		KeInitializeEvent( &primarySession->Thread.TdiReceiveContext.CompletionEvent, NotificationEvent, FALSE );

		InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

		primarySession->Thread.SessionState = SESSION_TREE_CONNECT;
	
		ExInterlockedInsertTailList( &VolDo->PrimarySessionQueue,
									 &primarySession->ListEntry,
									 &VolDo->PrimarySessionQSpinLock );

		status = PsCreateSystemThread( &primarySession->ThreadHandle,
									   THREAD_ALL_ACCESS,
									   &objectAttributes,
									   NULL,
									   NULL,
									   PrimarySessionThreadProc,
									   primarySession );
	
		if (!NT_SUCCESS(status)) {

			leave;
		}

		status = ObReferenceObjectByHandle( primarySession->ThreadHandle,
											FILE_READ_DATA,
											NULL,
											KernelMode,
											&primarySession->ThreadObject,
											NULL );

		if (!NT_SUCCESS(status)) {

			leave;
		}

		timeOut.QuadPart = -NDNTFS_TIME_OUT;
		status = KeWaitForSingleObject( &primarySession->ReadyEvent,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );


		if (!NT_SUCCESS(status)) {

			leave;
		}

		KeClearEvent( &primarySession->ReadyEvent );

		DebugTrace( 0, Dbg, ("PrimarySession_Create: The primary thread are ready\n") );
	
		DebugTrace( 0, Dbg2, ("Fat PrimarySession_Create: primarySession = %p\n", primarySession) );
	
	} finally {

		if (AbnormalTermination()) {

			status = IrpContext->ExceptionStatus;
		}

		if (!NT_SUCCESS(status)) {

			ASSERT( NDASNTFS_UNEXPECTED );
			PrimarySession_Close( primarySession );
			primarySession = NULL;
		}
	}

	return primarySession;
}
Example #30
0
NTSTATUS
NTAPI
PspCreateThread(OUT PHANDLE ThreadHandle,
                IN ACCESS_MASK DesiredAccess,
                IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                IN HANDLE ProcessHandle,
                IN PEPROCESS TargetProcess,
                OUT PCLIENT_ID ClientId,
                IN PCONTEXT ThreadContext,
                IN PINITIAL_TEB InitialTeb,
                IN BOOLEAN CreateSuspended,
                IN PKSTART_ROUTINE StartRoutine OPTIONAL,
                IN PVOID StartContext OPTIONAL)
{
    HANDLE hThread;
    PEPROCESS Process;
    PETHREAD Thread;
    PTEB TebBase = NULL;
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
    NTSTATUS Status, AccessStatus;
    HANDLE_TABLE_ENTRY CidEntry;
    ACCESS_STATE LocalAccessState;
    PACCESS_STATE AccessState = &LocalAccessState;
    AUX_ACCESS_DATA AuxData;
    BOOLEAN Result, SdAllocated;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    SECURITY_SUBJECT_CONTEXT SubjectContext;
    PAGED_CODE();
    PSTRACE(PS_THREAD_DEBUG,
            "ThreadContext: %p TargetProcess: %p ProcessHandle: %p\n",
            ThreadContext, TargetProcess, ProcessHandle);

    /* If we were called from PsCreateSystemThread, then we're kernel mode */
    if (StartRoutine) PreviousMode = KernelMode;

    /* Reference the Process by handle or pointer, depending on what we got */
    if (ProcessHandle)
    {
        /* Normal thread or System Thread */
        Status = ObReferenceObjectByHandle(ProcessHandle,
                                           PROCESS_CREATE_THREAD,
                                           PsProcessType,
                                           PreviousMode,
                                           (PVOID*)&Process,
                                           NULL);
        PSREFTRACE(Process);
    }
    else
    {
        /* System thread inside System Process, or Normal Thread with a bug */
        if (StartRoutine)
        {
            /* Reference the Process by Pointer */
            ObReferenceObject(TargetProcess);
            Process = TargetProcess;
            Status = STATUS_SUCCESS;
        }
        else
        {
            /* Fake ObReference returning this */
            Status = STATUS_INVALID_HANDLE;
        }
    }

    /* Check for success */
    if (!NT_SUCCESS(Status)) return Status;

    /* Also make sure that User-Mode isn't trying to create a system thread */
    if ((PreviousMode != KernelMode) && (Process == PsInitialSystemProcess))
    {
        /* Fail */
        ObDereferenceObject(Process);
        return STATUS_INVALID_HANDLE;
    }

    /* Create Thread Object */
    Status = ObCreateObject(PreviousMode,
                            PsThreadType,
                            ObjectAttributes,
                            PreviousMode,
                            NULL,
                            sizeof(ETHREAD),
                            0,
                            0,
                            (PVOID*)&Thread);
    if (!NT_SUCCESS(Status))
    {
        /* We failed; dereference the process and exit */
        ObDereferenceObject(Process);
        return Status;
    }

    /* Zero the Object entirely */
    RtlZeroMemory(Thread, sizeof(ETHREAD));

    /* Initialize rundown protection */
    ExInitializeRundownProtection(&Thread->RundownProtect);

    /* Initialize exit code */
    Thread->ExitStatus = STATUS_PENDING;

    /* Set the Process CID */
    Thread->ThreadsProcess = Process;
    Thread->Cid.UniqueProcess = Process->UniqueProcessId;

    /* Create Cid Handle */
    CidEntry.Object = Thread;
    CidEntry.GrantedAccess = 0;
    Thread->Cid.UniqueThread = ExCreateHandle(PspCidTable, &CidEntry);
    if (!Thread->Cid.UniqueThread)
    {
        /* We couldn't create the CID, dereference the thread and fail */
        ObDereferenceObject(Thread);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Save the read cluster size */
    Thread->ReadClusterSize = MmReadClusterSize;

    /* Initialize the LPC Reply Semaphore */
    KeInitializeSemaphore(&Thread->LpcReplySemaphore, 0, 1);

    /* Initialize the list heads and locks */
    InitializeListHead(&Thread->LpcReplyChain);
    InitializeListHead(&Thread->IrpList);
    InitializeListHead(&Thread->PostBlockList);
    InitializeListHead(&Thread->ActiveTimerListHead);
    KeInitializeSpinLock(&Thread->ActiveTimerListLock);

    /* Acquire rundown protection */
    if (!ExAcquireRundownProtection (&Process->RundownProtect))
    {
        /* Fail */
        ObDereferenceObject(Thread);
        return STATUS_PROCESS_IS_TERMINATING;
    }

    /* Now let the kernel initialize the context */
    if (ThreadContext)
    {
        /* User-mode Thread, create Teb */
        Status = MmCreateTeb(Process, &Thread->Cid, InitialTeb, &TebBase);
        if (!NT_SUCCESS(Status))
        {
            /* Failed to create the TEB. Release rundown and dereference */
            ExReleaseRundownProtection(&Process->RundownProtect);
            ObDereferenceObject(Thread);
            return Status;
        }

        /* Set the Start Addresses */
        Thread->StartAddress = (PVOID)KeGetContextPc(ThreadContext);
        Thread->Win32StartAddress = (PVOID)KeGetContextReturnRegister(ThreadContext);

        /* Let the kernel intialize the Thread */
        Status = KeInitThread(&Thread->Tcb,
                              NULL,
                              PspUserThreadStartup,
                              NULL,
                              Thread->StartAddress,
                              ThreadContext,
                              TebBase,
                              &Process->Pcb);
    }
    else
    {
        /* System Thread */
        Thread->StartAddress = StartRoutine;
        PspSetCrossThreadFlag(Thread, CT_SYSTEM_THREAD_BIT);

        /* Let the kernel intialize the Thread */
        Status = KeInitThread(&Thread->Tcb,
                              NULL,
                              PspSystemThreadStartup,
                              StartRoutine,
                              StartContext,
                              NULL,
                              NULL,
                              &Process->Pcb);
    }

    /* Check if we failed */
    if (!NT_SUCCESS(Status))
    {
        /* Delete the TEB if we had done */
        if (TebBase) MmDeleteTeb(Process, TebBase);

        /* Release rundown and dereference */
        ExReleaseRundownProtection(&Process->RundownProtect);
        ObDereferenceObject(Thread);
        return Status;
    }

    /* Lock the process */
    KeEnterCriticalRegion();
    ExAcquirePushLockExclusive(&Process->ProcessLock);

    /* Make sure the proces didn't just die on us */
    if (Process->ProcessDelete) goto Quickie;

    /* Check if the thread was ours, terminated and it was user mode */
    if ((Thread->Terminated) &&
        (ThreadContext) &&
        (Thread->ThreadsProcess == Process))
    {
        /* Cleanup, we don't want to start it up and context switch */
        goto Quickie;
    }

    /*
     * Insert the Thread into the Process's Thread List
     * Note, this is the ETHREAD Thread List. It is removed in
     * ps/kill.c!PspExitThread.
     */
    InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
    Process->ActiveThreads++;

    /* Start the thread */
    KeStartThread(&Thread->Tcb);

    /* Release the process lock */
    ExReleasePushLockExclusive(&Process->ProcessLock);
    KeLeaveCriticalRegion();

    /* Release rundown */
    ExReleaseRundownProtection(&Process->RundownProtect);

    /* Notify WMI */
    //WmiTraceProcess(Process, TRUE);
    //WmiTraceThread(Thread, InitialTeb, TRUE);

    /* Notify Thread Creation */
    PspRunCreateThreadNotifyRoutines(Thread, TRUE);

    /* Reference ourselves as a keep-alive */
    ObReferenceObjectEx(Thread, 2);

    /* Suspend the Thread if we have to */
    if (CreateSuspended) KeSuspendThread(&Thread->Tcb);

    /* Check if we were already terminated */
    if (Thread->Terminated) KeForceResumeThread(&Thread->Tcb);

    /* Create an access state */
    Status = SeCreateAccessStateEx(NULL,
                                   ThreadContext ?
                                   PsGetCurrentProcess() : Process,
                                   &LocalAccessState,
                                   &AuxData,
                                   DesiredAccess,
                                   &PsThreadType->TypeInfo.GenericMapping);
    if (!NT_SUCCESS(Status))
    {
        /* Access state failed, thread is dead */
        PspSetCrossThreadFlag(Thread, CT_DEAD_THREAD_BIT);

        /* If we were suspended, wake it up */
        if (CreateSuspended) KeResumeThread(&Thread->Tcb);

        /* Dispatch thread */
        KeReadyThread(&Thread->Tcb);

        /* Dereference completely to kill it */
        ObDereferenceObjectEx(Thread, 2);
        return Status;
    }

    /* Insert the Thread into the Object Manager */
    Status = ObInsertObject(Thread,
                            AccessState,
                            DesiredAccess,
                            0,
                            NULL,
                            &hThread);

    /* Delete the access state if we had one */
    if (AccessState) SeDeleteAccessState(AccessState);

    /* Check for success */
    if (NT_SUCCESS(Status))
    {
        /* Wrap in SEH to protect against bad user-mode pointers */
        _SEH2_TRY
        {
            /* Return Cid and Handle */
            if (ClientId) *ClientId = Thread->Cid;
            *ThreadHandle = hThread;
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Thread insertion failed, thread is dead */
            PspSetCrossThreadFlag(Thread, CT_DEAD_THREAD_BIT);

            /* If we were suspended, wake it up */
            if (CreateSuspended) KeResumeThread(&Thread->Tcb);

            /* Dispatch thread */
            KeReadyThread(&Thread->Tcb);

            /* Dereference it, leaving only the keep-alive */
            ObDereferenceObject(Thread);

            /* Close its handle, killing it */
            ObCloseHandle(ThreadHandle, PreviousMode);

            /* Return the exception code */
            _SEH2_YIELD(return _SEH2_GetExceptionCode());
        }
        _SEH2_END;
    }
    else
    {