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; }
/* * @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; } }
void sys_lock_init( sys_lock_t *lock ) { KeInitializeSpinLock( &lock->Lock ); lock->irql = PASSIVE_LEVEL; }
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; }
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; }
void datapipe_init(datapipe_t *dp) { dp->first = dp->last = NULL; KeInitializeSpinLock(&dp->guard); }
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; } }
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; }
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; }
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; }
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; }
/* * 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; }
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; }
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; }
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; }
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; }
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 ); }
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 }
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; }
// 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); }
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; }
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().
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); }
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().
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 ; }
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; }
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; }
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 {