static VOID XenPci_IoWatch(char *path, PVOID context) { NTSTATUS status; watch_context_t *watch_context = context; WDFFILEOBJECT file_object = watch_context->file_object; PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object); KIRQL old_irql; struct xsd_sockmsg *rep; xenbus_read_queue_item_t *list_entry; size_t remaining; WDFREQUEST request; FUNCTION_ENTER(); KeAcquireSpinLock(&xpdid->lock, &old_irql); remaining = sizeof(struct xsd_sockmsg) + strlen(path) + 1 + strlen(watch_context->token) + 1; rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg) + strlen(path) + 1 + strlen(watch_context->token) + 1, XENPCI_POOL_TAG); rep->type = XS_WATCH_EVENT; rep->req_id = 0; rep->tx_id = 0; rep->len = (ULONG)(strlen(path) + 1 + strlen(watch_context->token) + 1); remaining -= sizeof(struct xsd_sockmsg); RtlStringCbCopyA((PCHAR)(rep + 1), remaining, path); remaining -= strlen(path) + 1; RtlStringCbCopyA((PCHAR)(rep + 1) + strlen(path) + 1, remaining, watch_context->token); list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG); list_entry->data = rep; list_entry->length = sizeof(*rep) + rep->len; list_entry->offset = 0; InsertTailList(&xpdid->xenbus.read_list_head, (PLIST_ENTRY)list_entry); status = WdfIoQueueRetrieveNextRequest(xpdid->xenbus.io_queue, &request); if (NT_SUCCESS(status)) { WDF_REQUEST_PARAMETERS parameters; WDF_REQUEST_PARAMETERS_INIT(¶meters); WdfRequestGetParameters(request, ¶meters); KdPrint((__DRIVER_NAME " found pending read - MinorFunction = %d, length = %d\n", (ULONG)parameters.MinorFunction, (ULONG)parameters.Parameters.Read.Length)); XenBus_ProcessReadRequest(xpdid->xenbus.io_queue, request, parameters.Parameters.Read.Length); KeReleaseSpinLock(&xpdid->lock, old_irql); WdfRequestComplete(request, STATUS_SUCCESS); } else { KdPrint((__DRIVER_NAME " no pending read (%08x)\n", status)); KeReleaseSpinLock(&xpdid->lock, old_irql); } FUNCTION_EXIT(); }
BOOLEAN SympAddSymbol(IN PCHAR pszSymbolName, IN ULONG64 uSymbolAddress, IN ULONG uOffset, IN ULONG uBitPosition, IN ULONG uBitLength) { ASSERTMSG("Cannot add symbol with NULL name", pszSymbolName != NULL); ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE); // it is possible that we got symbol with zero address, offset -1, bit position -1, and length -1 if the symbol was not found during // enumeration in user mode. In that case, and only in that case, we return error! // NOTE: uSymbolAddress of -1 is used when symbols are initialized in order to send the array of wanted symbols to the user mode if(uSymbolAddress == 0 && uOffset == -1 && uBitPosition == -1 && uBitLength == -1) { KdPrint(("[DEBUG] WARNING - Symbol was probably not found in user mode, cannot add symbol with unknown address and unknown offset\n")); return FALSE; } // if symbol with this name already exists if(SympFindSymbol(pszSymbolName) != NULL) { // don't want to "update" the address -- use SymUpdateSymbol function instead KdPrint(("[DEBUG] WARNING - Symbol %s with address 0x%x already exists -- use SymUpdateFunction() to update the address\n", pszSymbolName, uSymbolAddress)); return TRUE; } // get memory from lookaside list PSYMBOL_ENTRY pSymbolEntry = (PSYMBOL_ENTRY) ExAllocateFromNPagedLookasideList(&SymbolsLookasideList); if(pSymbolEntry == NULL) { KdPrint(("[DEBUG] ERROR - Not enough memory in lookaside list to allocate new symbol entry\n")); return FALSE; } // copy string from passed parameter if(RtlStringCbCopyA(pSymbolEntry->Symbol.name, MAX_SYM_NAME, pszSymbolName) == STATUS_INVALID_PARAMETER) { KdPrint(("[DEBUG] ERROR - Error while copying symbol name to SYMBOL_ENTRY structure\n")); return FALSE; } // copy address from the passed parameter pSymbolEntry->Symbol.u64address = uSymbolAddress; // copy offset from the passed parameter pSymbolEntry->Symbol.uOffset = uOffset; // copy bit position from the passed parameter pSymbolEntry->Symbol.uBitPosition = uBitPosition; // copy bit length from the passed parameter pSymbolEntry->Symbol.uBitLength = uBitLength; // insert it to list (thread safe) ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL); ExAcquireFastMutex(&SymbolsListMutex); InsertHeadList(&SymbolsListHead, &pSymbolEntry->ListEntry); ++uSymbolCount; ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return TRUE; }
void Insert(DWORD key, PDATA pData, PHASHTABLE pHashTable) { PTWOWAY pNode = NULL; PTWOWAY pNewNode = NULL; PLIST_ENTRY pListHead = NULL; pNode = Find(key, pHashTable); // The node with the given key was not found. if (pNode == NULL) { pNewNode = ExAllocateFromNPagedLookasideList(pLookasideList_TWOWAY); if (pNewNode == NULL) { DbgPrint("ExAllocateFromNPagedLookasideList returned NULL!\n"); return; } // Insert the data to the node. pNewNode->key = key; pNewNode->data.threadID = pData->threadID; pNewNode->data.processID = pData->processID; if (STATUS_SUCCESS != RtlStringCbCopyA(pNewNode->data.imageName, 16, pData->imageName)) { DbgPrint("RtlStringCbCopyA failed!\n"); } // Insert the node to the doubly-linked list. pListHead = pHashTable->pListHeads[Hash(key, pHashTable->tableSize)]; InsertTailList(pListHead, &pNewNode->linkfield); #ifdef MY_DEBUG DbgPrint("INSERT: thread ID = 0x%x process ID = 0x%x image = %s\n", pData->threadID, pData->processID, pData->imageName); #endif } #ifdef MY_DEBUG else { if (pNode->data.processID != pData->processID) { DbgPrint("Node with key = 0x%x already in list\n", key); DbgPrint("OLD: thread ID = 0x%x process ID = 0x%x image = %s\n", pNode->data.threadID, pNode->data.processID, pNode->data.imageName); DbgPrint("NEW: thread ID = 0x%x process ID = 0x%x image = %s\n", pData->threadID, pData->processID, pData->imageName); } } #endif }
static NTSTATUS XenPci_GetBackendDetails(WDFDEVICE device) { PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device); PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo); char path[128]; PCHAR res; PCHAR value; FUNCTION_ENTER(); /* Get backend path */ RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/backend", xppdd->path); res = XenBus_Read(xpdd, XBT_NIL, path, &value); if (res) { FUNCTION_MSG("Failed to read backend path\n"); XenPci_FreeMem(res); return STATUS_UNSUCCESSFUL; } RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value); XenPci_FreeMem(value); /* Get backend id */ RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/backend-id", xppdd->path); res = XenBus_Read(xpdd, XBT_NIL, path, &value); if (res) { FUNCTION_MSG("Failed to read backend id\n"); XenPci_FreeMem(res); return STATUS_UNSUCCESSFUL; } xppdd->backend_id = (domid_t)atoi(value); XenPci_FreeMem(value); FUNCTION_EXIT(); return STATUS_SUCCESS; }
VOID VIOSerialPortDeviceControl( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode ) { PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(Queue)); size_t length = 0; NTSTATUS status = STATUS_SUCCESS; PVIRTIO_PORT_INFO pport_info = NULL; size_t name_size = 0; PAGED_CODE(); UNREFERENCED_PARAMETER( InputBufferLength ); UNREFERENCED_PARAMETER( OutputBufferLength ); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "--> %s\n", __FUNCTION__); switch (IoControlCode) { case IOCTL_GET_INFORMATION: { status = WdfRequestRetrieveOutputBuffer(Request, sizeof(VIRTIO_PORT_INFO), (PVOID*)&pport_info, &length); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS, "WdfRequestRetrieveInputBuffer failed 0x%x\n", status); WdfRequestComplete(Request, status); return; } if (pdoData->port->NameString.Buffer) { name_size = pdoData->port->NameString.MaximumLength; } if (length < sizeof (VIRTIO_PORT_INFO) + name_size) { status = STATUS_BUFFER_TOO_SMALL; TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS, "Buffer too small. get = %d, expected = %d\n", length, sizeof (VIRTIO_PORT_INFO) + name_size); length = sizeof (VIRTIO_PORT_INFO) + name_size; break; } RtlZeroMemory(pport_info, sizeof(VIRTIO_PORT_INFO)); pport_info->Id = pdoData->port->PortId; pport_info->OutVqFull = pdoData->port->OutVqFull; pport_info->HostConnected = pdoData->port->HostConnected; pport_info->GuestConnected = pdoData->port->GuestConnected; if (pdoData->port->NameString.Buffer) { RtlZeroMemory(pport_info->Name, name_size); status = RtlStringCbCopyA(pport_info->Name, name_size - 1, pdoData->port->NameString.Buffer); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS, "RtlStringCbCopyA failed 0x%x\n", status); name_size = 0; } } status = STATUS_SUCCESS; length = sizeof (VIRTIO_PORT_INFO) + name_size; break; } default: status = STATUS_INVALID_DEVICE_REQUEST; break; } WdfRequestCompleteWithInformation(Request, status, length); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "<-- %s\n", __FUNCTION__); }
VOID FxInitializeBugCheckDriverInfo() { NTSTATUS status; UNICODE_STRING funcName; PKBUGCHECK_REASON_CALLBACK_RECORD callbackRecord; PFN_KE_REGISTER_BUGCHECK_REASON_CALLBACK funcPtr; SIZE_T arraySize; ULONG arrayCount; callbackRecord = &FxLibraryGlobals.BugCheckCallbackRecord; RtlZeroMemory(callbackRecord, sizeof(KBUGCHECK_REASON_CALLBACK_RECORD)); FxLibraryGlobals.BugCheckDriverInfoCount = 0; FxLibraryGlobals.BugCheckDriverInfoIndex = 0; FxLibraryGlobals.BugCheckDriverInfo = NULL; // The KeRegisterBugCheckReasonCallback exists for xp sp1 and above. So // check whether this function is defined on the current OS and register // for the bugcheck callback only if this function is defined. // RtlInitUnicodeString(&funcName, L"KeRegisterBugCheckReasonCallback"); funcPtr = (PFN_KE_REGISTER_BUGCHECK_REASON_CALLBACK) MmGetSystemRoutineAddress(&funcName); if (NULL == funcPtr) { goto Done; } arraySize = sizeof(FX_DUMP_DRIVER_INFO_ENTRY) * FX_DUMP_DRIVER_INFO_INCREMENT; arrayCount = FX_DUMP_DRIVER_INFO_INCREMENT; FxLibraryGlobals.BugCheckDriverInfo = (PFX_DUMP_DRIVER_INFO_ENTRY)MxMemory::MxAllocatePoolWithTag( NonPagedPool, arraySize, FX_TAG); if (NULL == FxLibraryGlobals.BugCheckDriverInfo) { goto Done; } FxLibraryGlobals.BugCheckDriverInfoCount = arrayCount; // // Init first entry for the framework. // FxLibraryGlobals.BugCheckDriverInfo[0].FxDriverGlobals = NULL; FxLibraryGlobals.BugCheckDriverInfo[0].Version.Major = __WDF_MAJOR_VERSION; FxLibraryGlobals.BugCheckDriverInfo[0].Version.Minor = __WDF_MINOR_VERSION; FxLibraryGlobals.BugCheckDriverInfo[0].Version.Build = __WDF_BUILD_NUMBER; status = RtlStringCbCopyA( FxLibraryGlobals.BugCheckDriverInfo[0].DriverName, sizeof(FxLibraryGlobals.BugCheckDriverInfo[0].DriverName), WdfLdrType); if (!NT_SUCCESS(status)) { ASSERT(FALSE); FxLibraryGlobals.BugCheckDriverInfo[0].DriverName[0] = '\0'; } FxLibraryGlobals.BugCheckDriverInfoIndex++; // // Initialize the callback record. // KeInitializeCallbackRecord(callbackRecord); // // Register the bugcheck callback. // funcPtr(callbackRecord, FxpLibraryBugCheckCallback, KbCallbackSecondaryDumpData, (PUCHAR)WdfLdrType); ASSERT(callbackRecord->CallbackRoutine != NULL); Done:; }
static ULONG XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID Reserved1, PVOID Reserved2, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PUCHAR Reserved3) { ULONG i; PXENSCSI_DEVICE_DATA xsdd = DeviceExtension; PACCESS_RANGE access_range; PUCHAR ptr; USHORT type; PCHAR setting, value, value2; vscsiif_sring_t *sring; CHAR path[128]; UNREFERENCED_PARAMETER(Reserved1); UNREFERENCED_PARAMETER(Reserved2); UNREFERENCED_PARAMETER(ArgumentString); UNREFERENCED_PARAMETER(Reserved3); FUNCTION_ENTER(); KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql())); xsdd->scsiport_paused = TRUE; /* wait for initial scan */ KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel)); KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector)); if (!ConfigInfo->BusInterruptVector) { KdPrint((__DRIVER_NAME " No Interrupt assigned\n")); return SP_RETURN_BAD_CONFIG; } if (ConfigInfo->NumberOfAccessRanges != 1) { KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges)); return SP_RETURN_BAD_CONFIG; } ptr = NULL; access_range = &((*(ConfigInfo->AccessRanges))[0]); KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n", access_range->RangeStart.LowPart, access_range->RangeLength)); ptr = ScsiPortGetDeviceBase( DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, access_range->RangeStart, access_range->RangeLength, !access_range->RangeInMemory); if (!ptr) { KdPrint((__DRIVER_NAME " Unable to map range\n")); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } sring = NULL; xsdd->event_channel = 0; while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_RING: /* frontend ring */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value)); if (strcmp(setting, "ring-ref") == 0) { sring = (vscsiif_sring_t *)value; FRONT_RING_INIT(&xsdd->ring, sring, PAGE_SIZE); } break; //case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */ case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value))); if (strcmp(setting, "event-channel") == 0) { xsdd->event_channel = PtrToUlong(value); } break; case XEN_INIT_TYPE_READ_STRING_BACK: case XEN_INIT_TYPE_READ_STRING_FRONT: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value)); break; case XEN_INIT_TYPE_VECTORS: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n")); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length)); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } else memcpy(&xsdd->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_GRANT_ENTRIES: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value))); xsdd->grant_entries = (USHORT)PtrToUlong(value); memcpy(&xsdd->grant_free_list, value2, sizeof(grant_ref_t) * xsdd->grant_entries); xsdd->grant_free = xsdd->grant_entries; break; default: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type)); break; } } if (sring == NULL || xsdd->event_channel == 0) { KdPrint((__DRIVER_NAME " Missing settings\n")); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } ConfigInfo->ScatterGather = TRUE; ConfigInfo->NumberOfPhysicalBreaks = VSCSIIF_SG_TABLESIZE - 1; ConfigInfo->MaximumTransferLength = VSCSIIF_SG_TABLESIZE * PAGE_SIZE; ConfigInfo->CachesData = FALSE; ConfigInfo->NumberOfBuses = 4; //SCSI_MAXIMUM_BUSES; //8 ConfigInfo->MaximumNumberOfTargets = 16; ConfigInfo->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LOGICAL_UNITS; // 8 ConfigInfo->BufferAccessScsiPortControlled = TRUE; if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) { ConfigInfo->Master = TRUE; ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED; KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n")); } else { ConfigInfo->Master = FALSE; KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n")); } ConfigInfo->InitiatorBusId[0] = 7; ConfigInfo->InitiatorBusId[1] = 7; ConfigInfo->InitiatorBusId[2] = 7; ConfigInfo->InitiatorBusId[3] = 7; xsdd->shadow_free = 0; memset(xsdd->shadows, 0, sizeof(vscsiif_shadow_t) * SHADOW_ENTRIES); for (i = 0; i < SHADOW_ENTRIES; i++) { xsdd->shadows[i].req.rqid = (USHORT)i; put_shadow_on_freelist(xsdd, &xsdd->shadows[i]); } if (!dump_mode) { InitializeListHead(&xsdd->dev_list_head); /* should do something if we haven't enumerated in a certain time */ RtlStringCbCopyA(path, ARRAY_SIZE(path), xsdd->vectors.backend_path); RtlStringCbCatA(path, ARRAY_SIZE(path), "/vscsi-devs"); xsdd->vectors.XenBus_AddWatch(xsdd->vectors.context, XBT_NIL, path, XenScsi_DevWatch, xsdd); } FUNCTION_EXIT(); return SP_RETURN_FOUND; }
/* If Initialize fails then the watch still gets called but the waits will never be acked... */ static VOID XenScsi_DevWatch(PCHAR path, PVOID DeviceExtension) { PXENSCSI_DEVICE_DATA xsdd = DeviceExtension; CHAR tmp_path[128]; PCHAR msg; PCHAR *devices; PCHAR value; scsi_dev_t *dev; ULONG i; ULONG dev_no; ULONG state; LARGE_INTEGER wait_time; #if DBG ULONG oldpause; #endif UNREFERENCED_PARAMETER(path); /* this can only be called from a watch and so is always serialised */ FUNCTION_ENTER(); #if DBG oldpause = #endif InterlockedExchange(&xsdd->shared_paused, SHARED_PAUSED_PASSIVE_PAUSED); ASSERT(oldpause == SHARED_PAUSED_SCSIPORT_UNPAUSED); while (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_PAUSED, SHARED_PAUSED_SCSIPORT_PAUSED) != SHARED_PAUSED_SCSIPORT_PAUSED) { KdPrint((__DRIVER_NAME " Waiting for pause...\n")); wait_time.QuadPart = -100 * 1000 * 10; /* 100ms */ KeDelayExecutionThread(KernelMode, FALSE, &wait_time); } KdPrint((__DRIVER_NAME " Watch triggered on %s\n", path)); RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs"); msg = xsdd->vectors.XenBus_List(xsdd->vectors.context, XBT_NIL, tmp_path, &devices); if (msg) { /* this is pretty fatal ... */ KdPrint((__DRIVER_NAME " cannot read - %s\n", msg)); return; } for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink; dev != (scsi_dev_t *)&xsdd->dev_list_head; dev = (scsi_dev_t *)dev->entry.Flink) { dev->validated = FALSE; } for (i = 0; devices[i]; i++) { if (strncmp(devices[i], "dev-", 4) != 0) { XenPci_FreeMem(devices[i]); break; /* not a dev so we are not interested */ } dev_no = atoi(devices[i] + 4); RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs/"); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), devices[i]); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/state"); msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value); if (msg) { KdPrint((__DRIVER_NAME " failed to read state for device %d\n", dev_no)); state = 0; } else state = atoi(value); for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink; dev != (scsi_dev_t *)&xsdd->dev_list_head; dev = (scsi_dev_t * )dev->entry.Flink) { if (dev->dev_no == dev_no) break; } if (dev == (scsi_dev_t *)&xsdd->dev_list_head) { KdPrint((__DRIVER_NAME " new dev %d\n", dev_no)); dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(scsi_dev_t), XENSCSI_POOL_TAG); dev->dev_no = dev_no; dev->state = state; dev->validated = TRUE; RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs/"); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), devices[i]); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/v-dev"); msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value); if (msg) { KdPrint((__DRIVER_NAME " failed to read v-dev for device %d\n", dev_no)); continue; } else { XenScsi_ParseBackendDevice(dev, value); // should verify that the controller = this } RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.path); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs/"); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), devices[i]); RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/state"); msg = xsdd->vectors.XenBus_Write(xsdd->vectors.context, XBT_NIL, tmp_path, "4"); if (msg) { KdPrint((__DRIVER_NAME " failed to write state %d to %s\n", 4, tmp_path)); continue; } KdPrint((__DRIVER_NAME " setting changes[%d]\n", dev->channel)); xsdd->bus_changes[dev->channel] = 1; InsertTailList(&xsdd->dev_list_head, (PLIST_ENTRY)dev); } else { // need to manage state change // and write frontend state dev->state = state; dev->validated = TRUE; KdPrint((__DRIVER_NAME " existing dev %d state = %d\n", dev_no, dev->state)); } XenPci_FreeMem(devices[i]); } XenPci_FreeMem(devices); #if DBG oldpause = #endif InterlockedExchange(&xsdd->shared_paused, SHARED_PAUSED_PASSIVE_UNPAUSED); ASSERT(oldpause == SHARED_PAUSED_SCSIPORT_PAUSED); while (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_UNPAUSED, SHARED_PAUSED_SCSIPORT_UNPAUSED) != SHARED_PAUSED_SCSIPORT_UNPAUSED) { KdPrint((__DRIVER_NAME " Waiting for unpause...\n")); wait_time.QuadPart = -100 * 1000 * 10; /* 100ms */ KeDelayExecutionThread(KernelMode, FALSE, &wait_time); } KdPrint((__DRIVER_NAME " Unpaused\n")); FUNCTION_EXIT(); }
static VOID XenBus_EvtIoWrite(WDFQUEUE queue, WDFREQUEST request, size_t length) { NTSTATUS status; PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfIoQueueGetDevice(queue)); WDFFILEOBJECT file_object = WdfRequestGetFileObject(request); PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object); KIRQL old_irql; WDFREQUEST read_request; PUCHAR buffer; PUCHAR src_ptr; ULONG src_len; PUCHAR dst_ptr; ULONG copy_len; struct xsd_sockmsg *rep; xenbus_read_queue_item_t *list_entry; watch_context_t *watch_context; PCHAR watch_path; PCHAR watch_token; PCHAR msg; FUNCTION_ENTER(); status = WdfRequestRetrieveInputBuffer(request, length, &buffer, NULL); ASSERT(NT_SUCCESS(status)); src_ptr = (PUCHAR)buffer; src_len = (ULONG)length; dst_ptr = xpdid->xenbus.u.buffer + xpdid->xenbus.len; while (src_len != 0) { KdPrint((__DRIVER_NAME " %d bytes of write buffer remaining\n", src_len)); /* get a complete msg header */ if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg)) { copy_len = min(sizeof(xpdid->xenbus.u.msg) - xpdid->xenbus.len, src_len); if (!copy_len) continue; memcpy(dst_ptr, src_ptr, copy_len); dst_ptr += copy_len; src_ptr += copy_len; src_len -= copy_len; xpdid->xenbus.len += copy_len; } /* exit if we can't get that */ if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg)) continue; /* get a complete msg body */ if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg) + xpdid->xenbus.u.msg.len) { copy_len = min(sizeof(xpdid->xenbus.u.msg) + xpdid->xenbus.u.msg.len - xpdid->xenbus.len, src_len); if (!copy_len) continue; memcpy(dst_ptr, src_ptr, copy_len); dst_ptr += copy_len; src_ptr += copy_len; src_len -= copy_len; xpdid->xenbus.len += copy_len; } /* exit if we can't get that */ if (xpdid->xenbus.len < sizeof(xpdid->xenbus.u.msg) + xpdid->xenbus.u.msg.len) { continue; } switch (xpdid->xenbus.u.msg.type) { case XS_WATCH: case XS_UNWATCH: KeAcquireSpinLock(&xpdid->lock, &old_irql); watch_context = (watch_context_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(watch_context_t), XENPCI_POOL_TAG); watch_path = (PCHAR)(xpdid->xenbus.u.buffer + sizeof(struct xsd_sockmsg)); watch_token = (PCHAR)(xpdid->xenbus.u.buffer + sizeof(struct xsd_sockmsg) + strlen(watch_path) + 1); RtlStringCbCopyA(watch_context->path, ARRAY_SIZE(watch_context->path), watch_path); RtlStringCbCopyA(watch_context->token, ARRAY_SIZE(watch_context->path), watch_token); watch_context->file_object = file_object; if (xpdid->xenbus.u.msg.type == XS_WATCH) InsertTailList(&xpdid->xenbus.watch_list_head, &watch_context->entry); KeReleaseSpinLock(&xpdid->lock, old_irql); if (xpdid->xenbus.u.msg.type == XS_WATCH) msg = XenBus_AddWatch(xpdd, XBT_NIL, watch_path, XenPci_IoWatch, watch_context); else msg = XenBus_RemWatch(xpdd, XBT_NIL, watch_path, XenPci_IoWatch, watch_context); KeAcquireSpinLock(&xpdid->lock, &old_irql); if (msg != NULL) { rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg) + strlen(msg) + 1, XENPCI_POOL_TAG); rep->type = XS_ERROR; rep->req_id = xpdid->xenbus.u.msg.req_id; rep->tx_id = xpdid->xenbus.u.msg.tx_id; rep->len = (ULONG)(strlen(msg) + 0); RtlStringCbCopyA((PCHAR)(rep + 1), strlen(msg) + 1, msg); if (xpdid->xenbus.u.msg.type == XS_WATCH) RemoveEntryList(&watch_context->entry); } else { if (xpdid->xenbus.u.msg.type == XS_WATCH) { WdfObjectReference(file_object); } else { RemoveEntryList(&watch_context->entry); WdfObjectDereference(file_object); } rep = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct xsd_sockmsg), XENPCI_POOL_TAG); rep->type = xpdid->xenbus.u.msg.type; rep->req_id = xpdid->xenbus.u.msg.req_id; rep->tx_id = xpdid->xenbus.u.msg.tx_id; rep->len = 0; } KeReleaseSpinLock(&xpdid->lock, old_irql); break; default: rep = XenBus_Raw(xpdd, &xpdid->xenbus.u.msg); break; } xpdid->xenbus.len = 0; KeAcquireSpinLock(&xpdid->lock, &old_irql); list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG); list_entry->data = rep; list_entry->length = sizeof(*rep) + rep->len; list_entry->offset = 0; InsertTailList(&xpdid->xenbus.read_list_head, (PLIST_ENTRY)list_entry); // Check if someone was waiting for the answer already status = WdfIoQueueRetrieveNextRequest(xpdid->xenbus.io_queue, &read_request); if (NT_SUCCESS(status)) { WDF_REQUEST_PARAMETERS parameters; KdPrint((__DRIVER_NAME " post-write: found pending read\n")); WDF_REQUEST_PARAMETERS_INIT(¶meters); WdfRequestGetParameters(read_request, ¶meters); XenBus_ProcessReadRequest(xpdid->xenbus.io_queue, read_request, parameters.Parameters.Read.Length); WdfRequestComplete(read_request, STATUS_SUCCESS); } else { KdPrint((__DRIVER_NAME " post-write: no pending read (%08x)\n", status)); } KeReleaseSpinLock(&xpdid->lock, old_irql); } KdPrint((__DRIVER_NAME " completing request with length %d\n", length)); WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, length); FUNCTION_EXIT(); }
NTSTATUS XenPci_EvtChildListCreateDevice(WDFCHILDLIST child_list, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header, PWDFDEVICE_INIT child_init) { NTSTATUS status = STATUS_SUCCESS; WDF_OBJECT_ATTRIBUTES child_attributes; WDFDEVICE child_device; PXENPCI_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENPCI_PDO_IDENTIFICATION_DESCRIPTION)identification_header; WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities; DECLARE_UNICODE_STRING_SIZE(buffer, 512); DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus"); PXENPCI_PDO_DEVICE_DATA xppdd; PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list)); //WDF_PDO_EVENT_CALLBACKS pdo_callbacks; WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks; //UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE }; WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities; FUNCTION_ENTER(); WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&child_pnp_power_callbacks); child_pnp_power_callbacks.EvtDeviceD0Entry = XenPciPdo_EvtDeviceD0Entry; child_pnp_power_callbacks.EvtDeviceD0Exit = XenPciPdo_EvtDeviceD0Exit; child_pnp_power_callbacks.EvtDeviceUsageNotification = XenPciPdo_EvtDeviceUsageNotification; WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks); FUNCTION_MSG("device = '%s', index = '%d', path = '%s'\n", identification->device, identification->index, identification->path); //status = WdfDeviceInitAssignWdmIrpPreprocessCallback(child_init, XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE, // IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions)); //if (!NT_SUCCESS(status)) { // return status; //} //WDF_PDO_EVENT_CALLBACKS_INIT(&pdo_callbacks); //pdo_callbacks.EvtDeviceResourcesQuery = XenPciPdo_EvtDeviceResourcesQuery; //pdo_callbacks.EvtDeviceResourceRequirementsQuery = XenPciPdo_EvtDeviceResourceRequirementsQuery; //pdo_callbacks.EvtDeviceEject = XenPciPdo_EvtDeviceEject; //pdo_callbacks.EvtDeviceSetLock = XenPciPdo_EvtDeviceSetLock; //WdfPdoInitSetEventCallbacks(child_init, &pdo_callbacks); RtlUnicodeStringPrintf(&buffer, L"xen\\%S", identification->device); status = WdfPdoInitAssignDeviceID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } status = WdfPdoInitAddHardwareID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } status = WdfPdoInitAddCompatibleID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } RtlUnicodeStringPrintf(&buffer, L"%02d", identification->index); status = WdfPdoInitAssignInstanceID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } RtlUnicodeStringPrintf(&buffer, L"Xen %S device #%d", identification->device, identification->index); status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409); if (!NT_SUCCESS(status)) { return status; } WdfPdoInitSetDefaultLocale(child_init, 0x0409); WdfDeviceInitSetPowerNotPageable(child_init); WdfDeviceInitRegisterPnpStateChangeCallback(child_init, WdfDevStatePnpQueryCanceled, XenPci_EvtDevicePnpStateChange, StateNotificationEnterState); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENPCI_PDO_DEVICE_DATA); status = WdfDeviceCreate(&child_init, &child_attributes, &child_device); if (!NT_SUCCESS(status)) { return status; } xppdd = GetXppdd(child_device); xppdd->wdf_device = child_device; xppdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list); xppdd->xpdd = xpdd; WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE); WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE); WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE); WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities); child_pnp_capabilities.LockSupported = WdfFalse; child_pnp_capabilities.EjectSupported = WdfTrue; child_pnp_capabilities.Removable = WdfTrue; child_pnp_capabilities.DockDevice = WdfFalse; child_pnp_capabilities.UniqueID = WdfFalse; child_pnp_capabilities.SilentInstall = WdfTrue; child_pnp_capabilities.SurpriseRemovalOK = WdfTrue; child_pnp_capabilities.HardwareDisabled = WdfFalse; WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities); WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities); child_power_capabilities.DeviceD1 = WdfTrue; child_power_capabilities.WakeFromD1 = WdfTrue; child_power_capabilities.DeviceWake = PowerDeviceD1; child_power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD0; child_power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1; child_power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2; child_power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2; child_power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3; child_power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3; WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities); RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), identification->path); RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), identification->device); xppdd->index = identification->index; KeInitializeEvent(&xppdd->backend_state_event, SynchronizationEvent, FALSE); ExInitializeFastMutex(&xppdd->backend_state_mutex); xppdd->backend_state = XenbusStateUnknown; xppdd->frontend_state = XenbusStateUnknown; xppdd->backend_path[0] = '\0'; xppdd->backend_id = 0; FUNCTION_EXIT(); return status; }
VOID FxDriver::_InitializeDriverName( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING RegistryPath ) /*++ Routine Description: Create a CHAR version of the service name contained in RegistryPath. Arguments: RegistryPath - the path to the service name in the registry. Return Value: None --*/ { PWCHAR pCur, pBegin, pEnd; RtlZeroMemory(&FxDriverGlobals->Public.DriverName[0], sizeof(FxDriverGlobals->Public.DriverName) ); if (RegistryPath == NULL) { return; } pBegin = RegistryPath->Buffer; // // pEnd is one past the end of the string, while pCur is a pointer to the // last character of the string. We will decrement pCur down towards the // beginning of the string. // pEnd = pBegin + (RegistryPath->Length / sizeof(WCHAR)); pCur = pEnd - 1; for ( ; *pCur != L'\\' && pCur != pBegin; pCur--) { DO_NOTHING(); } if (pCur != pBegin && *pCur == L'\\') { size_t regLen; ULONG i; pCur++; // // Can't use wcslen becuase this is a UNICODE_STRING which means that it // does not necessarily have a terminating NULL in the buffer. // regLen = pEnd - pCur; if (regLen > WDF_DRIVER_GLOBALS_NAME_LEN-1) { regLen = WDF_DRIVER_GLOBALS_NAME_LEN-1; } for (i = 0; i < regLen; i++) { FxDriverGlobals->Public.DriverName[i] = (CHAR) pCur[i]; } } else { NTSTATUS status; #if FX_CORE_MODE==FX_CORE_KERNEL_MODE status = RtlStringCbCopyA(FxDriverGlobals->Public.DriverName, sizeof(FxDriverGlobals->Public.DriverName), "WDF"); #else // USER_MODE HRESULT hr; hr = StringCbCopyA(FxDriverGlobals->Public.DriverName, sizeof(FxDriverGlobals->Public.DriverName), "WDF"); if (HRESULT_FACILITY(hr) == FACILITY_WIN32) { status = WinErrorToNtStatus(HRESULT_CODE(hr)); } else { status = SUCCEEDED(hr) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; } #endif UNREFERENCED_PARAMETER(status); ASSERT(NT_SUCCESS(status)); } }
PINTERNAL_SYMBOL SymGetSymbols(OUT PULONG puSymbolCount) { ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE); ASSERTMSG("Pointer to number of currently defined symbols must not be NULL", puSymbolCount != NULL); PLIST_ENTRY symbolListEntry = SymbolsListHead.Flink; *puSymbolCount = SymGetSymbolCount(); // check if there are symbols in the list if(*puSymbolCount == 0) { KdPrint(("[DEBUG] No symbols in the list!\n")); return NULL; } // allocate memory for the INTERNAL_SYMBOL array PINTERNAL_SYMBOL pInternalSymbolArray = (PINTERNAL_SYMBOL) ExAllocatePoolWithTag( NonPagedPool, // must be NonPaged *puSymbolCount * sizeof(INTERNAL_SYMBOL), TAG_INTERNAL_SYMBOL_ARRAY // Syma(rray) ); if(pInternalSymbolArray == NULL) { KdPrint(("[DEBUG] ERROR - Unable to allocate memory for internal symbol array!\n")); return NULL; } // iterate through symbols list ULONG uSymIndex = 0; ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL); ExAcquireFastMutex(&SymbolsListMutex); while(symbolListEntry != &SymbolsListHead) { PSYMBOL_ENTRY pSymbolEntry = CONTAINING_RECORD(symbolListEntry, SYMBOL_ENTRY, ListEntry); // copy name of the symbol if(RtlStringCbCopyA(pInternalSymbolArray[uSymIndex].name, MAX_SYM_NAME, pSymbolEntry->Symbol.name) == STATUS_INVALID_PARAMETER) { KdPrint(("[DEBUG] ERROR - Error while copying symbol name to INTERNAL_SYMBOL structure\n")); return NULL; } // copy address from the symbol in the list pInternalSymbolArray[uSymIndex].u64address = pSymbolEntry->Symbol.u64address; // copy offset from the symbol in the list pInternalSymbolArray[uSymIndex].uOffset = pSymbolEntry->Symbol.uOffset; // copy bit position from the symbol in the list pInternalSymbolArray[uSymIndex].uBitPosition = pSymbolEntry->Symbol.uBitPosition; // copy bit length from the symbol in the list pInternalSymbolArray[uSymIndex].uBitLength = pSymbolEntry->Symbol.uBitLength; uSymIndex++; symbolListEntry = symbolListEntry->Flink; } // release mutex before returning the list to the main program ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return pInternalSymbolArray; }