VOID EnListPacket( PADAPT pAdapt, IN PNDIS_PACKET pRcvPacket ) /*++ Routine Description: 将一个接收到的包挂在接收包队列上。如果队列长度过长的话就丢弃一些包 最后,通知并运行接收包例程 Arguments: pRcvPacket - 接收到的包 Return Value: None --*/ { PLIST_ENTRY pListEntry; PLIST_ENTRY pDiscardEntry; PNDIS_PACKET pDiscardPacket; P_PACKET_TOTAL pPacketTotal; P_PACKET_TOTAL pDiscardTotal; USHORT Len; do { //将packet转化为PACKET_TOTAL结构,即给它加上ListEntry项 pListEntry = SECLAB_RCV_PKT_TO_LIST_ENTRY(pRcvPacket); //将此包加入到接收包队列中 NdisAcquireSpinLock(&PacketListLock); InsertTailList(&PacketList,pListEntry); PacketCount++; NdisReleaseSpinLock(&PacketListLock); // // 检查接收包队列是否过长 // NdisAcquireSpinLock(&PacketListLock); if (PacketCount > MAX_RECV_QUEUE_SIZE) { // // 删除队列头的包. // pDiscardEntry = PacketList.Flink; RemoveEntryList(pDiscardEntry); PacketCount--; // 得到封包 pDiscardPacket = SECLAB_LIST_ENTRY_TO_RCV_PKT(pDiscardEntry); SecLabFreeReceivePacket(pAdapt,pDiscardPacket); } NdisReleaseSpinLock(&PacketListLock); // // 运行接收包例程 // NdisAcquireSpinLock(&ReadIrpLock); if(ReadIrp!=NULL && ReadIrp->IoStatus.Status == STATUS_PENDING/*&& ReadCount!=0*/) { if(PickPacketFromList(pAdapt,ReadIrp)) { ReadIrp=NULL; ReadCount=0; } } NdisReleaseSpinLock(&ReadIrpLock); } while (FALSE); }
NTSTATUS WdmAudOpenSysAudioDevices( IN PDEVICE_OBJECT DeviceObject, IN PWDMAUD_DEVICE_EXTENSION DeviceExtension) { NTSTATUS Status = STATUS_SUCCESS; LPWSTR SymbolicLinkList; SYSAUDIO_ENTRY * Entry; ULONG Length; HANDLE hSysAudio; PFILE_OBJECT FileObject; UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio\\GLOBAL"); if (DeviceExtension->DeviceInterfaceSupport) { Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO, NULL, 0, &SymbolicLinkList); if (NT_SUCCESS(Status)) { WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList); FreeItem(SymbolicLinkList); } Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&KSCATEGORY_SYSAUDIO, DeviceObject->DriverObject, DeviceInterfaceChangeCallback, (PVOID)DeviceExtension, &DeviceExtension->SysAudioNotification); } else { Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY)); if (!Entry) { return STATUS_INSUFFICIENT_RESOURCES; } Length = wcslen(DeviceName.Buffer) + 1; Entry->SymbolicLink.Length = 0; Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR); Entry->SymbolicLink.Buffer = AllocateItem(NonPagedPool, Entry->SymbolicLink.MaximumLength); if (!Entry->SymbolicLink.Buffer) { FreeItem(Entry); return STATUS_INSUFFICIENT_RESOURCES; } Status = RtlAppendUnicodeStringToString(&Entry->SymbolicLink, &DeviceName); if (!NT_SUCCESS(Status)) { FreeItem(Entry->SymbolicLink.Buffer); FreeItem(Entry); return Status; } InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry); DeviceExtension->NumSysAudioDevices++; DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer); Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open sysaudio %x\n", Status); return Status; } /* get the file object */ Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to reference FileObject %x\n", Status); ZwClose(hSysAudio); return Status; } DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension->hSysAudio = hSysAudio; DeviceExtension->FileObject = FileObject; } return Status; }
VOID ExInitializeSystemLookasideList ( IN PGENERAL_LOOKASIDE Lookaside, IN POOL_TYPE Type, IN ULONG Size, IN ULONG Tag, IN USHORT Depth, IN PLIST_ENTRY ListHead ) /*++ Routine Description: This function initializes a system lookaside list structure and inserts the structure in the specified lookaside list. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Type - Supplies the pool type of the lookaside list. Size - Supplies the size of the lookaside list entries. Tag - Supplies the pool tag for the lookaside list entries. Depth - Supplies the maximum depth of the lookaside list. ListHead - Supplies a pointer to the lookaside list into which the lookaside list structure is to be inserted. Return Value: None. --*/ { // // Initialize pool lookaside list structure and insert the structure // in the pool lookaside list. // ExInitializeSListHead(&Lookaside->ListHead); Lookaside->Allocate = &ExAllocatePoolWithTag; Lookaside->Free = &ExFreePool; Lookaside->Depth = 2; Lookaside->MaximumDepth = Depth; Lookaside->TotalAllocates = 0; Lookaside->AllocateHits = 0; Lookaside->TotalFrees = 0; Lookaside->FreeHits = 0; Lookaside->Type = Type; Lookaside->Tag = Tag; Lookaside->Size = Size; Lookaside->LastTotalAllocates = 0; Lookaside->LastAllocateHits = 0; InsertTailList(ListHead, &Lookaside->ListEntry); return; }
/** Add an SMBIOS record. @param This The EFI_SMBIOS_PROTOCOL instance. @param ProducerHandle The handle of the controller or driver associated with the SMBIOS information. NULL means no handle. @param SmbiosHandle On entry, the handle of the SMBIOS record to add. If FFFEh, then a unique handle will be assigned to the SMBIOS record. If the SMBIOS handle is already in use, EFI_ALREADY_STARTED is returned and the SMBIOS record is not updated. @param Record The data for the fixed portion of the SMBIOS record. The format of the record is determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or a set of null terminated strings and a null. @retval EFI_SUCCESS Record was added. @retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system resources. @retval EFI_ALREADY_STARTED The SmbiosHandle passed in was already in use. **/ EFI_STATUS EFIAPI SmbiosAdd ( IN CONST EFI_SMBIOS_PROTOCOL *This, IN EFI_HANDLE ProducerHandle, OPTIONAL IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle, IN EFI_SMBIOS_TABLE_HEADER *Record ) { VOID *Raw; UINTN TotalSize; UINTN RecordSize; UINTN StructureSize; UINTN NumberOfStrings; EFI_STATUS Status; LIST_ENTRY *Head; SMBIOS_INSTANCE *Private; EFI_SMBIOS_ENTRY *SmbiosEntry; EFI_SMBIOS_HANDLE MaxSmbiosHandle; SMBIOS_HANDLE_ENTRY *HandleEntry; EFI_SMBIOS_RECORD_HEADER *InternalRecord; BOOLEAN Smbios32BitTable; BOOLEAN Smbios64BitTable; if (SmbiosHandle == NULL) { return EFI_INVALID_PARAMETER; } Private = SMBIOS_INSTANCE_FROM_THIS (This); // // Check whether SmbiosHandle is already in use // Head = &Private->AllocatedHandleListHead; if (*SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED && CheckSmbiosHandleExistance(Head, *SmbiosHandle)) { return EFI_ALREADY_STARTED; } // // when SmbiosHandle is 0xFFFE, an available handle will be assigned // if (*SmbiosHandle == SMBIOS_HANDLE_PI_RESERVED) { Status = GetAvailableSmbiosHandle(This, SmbiosHandle); if (EFI_ERROR(Status)) { return Status; } } else { // // Check this handle validity // GetMaxSmbiosHandle(This, &MaxSmbiosHandle); if (*SmbiosHandle > MaxSmbiosHandle) { return EFI_INVALID_PARAMETER; } } // // Calculate record size and string number // Status = GetSmbiosStructureSize(This, Record, &StructureSize, &NumberOfStrings); if (EFI_ERROR(Status)) { return Status; } Smbios32BitTable = FALSE; Smbios64BitTable = FALSE; if ((This->MajorVersion < 0x3) || ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) { // // For SMBIOS 32-bit table, the length of the entire structure table (including all strings) must be reported // in the Structure Table Length field of the SMBIOS Structure Table Entry Point, // which is a WORD field limited to 65,535 bytes. So the max size of 32-bit table should not exceed 65,535 bytes. // if ((EntryPointStructure != NULL) && (EntryPointStructure->TableLength + StructureSize > SMBIOS_TABLE_MAX_LENGTH)) { DEBUG ((EFI_D_INFO, "SmbiosAdd: Total length exceeds max 32-bit table length with type = %d size = 0x%x\n", Record->Type, StructureSize)); } else { Smbios32BitTable = TRUE; DEBUG ((EFI_D_INFO, "SmbiosAdd: Smbios type %d with size 0x%x is added to 32-bit table\n", Record->Type, StructureSize)); } } // // For SMBIOS 3.0, Structure table maximum size in Entry Point structure is DWORD field limited to 0xFFFFFFFF bytes. // if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) { // // For SMBIOS 64-bit table, Structure table maximum size in SMBIOS 3.0 (64-bit) Entry Point // is a DWORD field limited to 0xFFFFFFFF bytes. So the max size of 64-bit table should not exceed 0xFFFFFFFF bytes. // if ((Smbios30EntryPointStructure != NULL) && (Smbios30EntryPointStructure->TableMaximumSize + StructureSize > SMBIOS_3_0_TABLE_MAX_LENGTH)) { DEBUG ((EFI_D_INFO, "SmbiosAdd: Total length exceeds max 64-bit table length with type = %d size = 0x%x\n", Record->Type, StructureSize)); } else { DEBUG ((EFI_D_INFO, "SmbiosAdd: Smbios type %d with size 0x%x is added to 64-bit table\n", Record->Type, StructureSize)); Smbios64BitTable = TRUE; } } if ((!Smbios32BitTable) && (!Smbios64BitTable)) { // // If both 32-bit and 64-bit table are not updated, quit // return EFI_OUT_OF_RESOURCES; } // // Enter into critical section // Status = EfiAcquireLockOrFail (&Private->DataLock); if (EFI_ERROR (Status)) { return Status; } RecordSize = sizeof (EFI_SMBIOS_RECORD_HEADER) + StructureSize; TotalSize = sizeof (EFI_SMBIOS_ENTRY) + RecordSize; // // Allocate internal buffer // SmbiosEntry = AllocateZeroPool (TotalSize); if (SmbiosEntry == NULL) { EfiReleaseLock (&Private->DataLock); return EFI_OUT_OF_RESOURCES; } HandleEntry = AllocateZeroPool (sizeof(SMBIOS_HANDLE_ENTRY)); if (HandleEntry == NULL) { EfiReleaseLock (&Private->DataLock); return EFI_OUT_OF_RESOURCES; } // // Build Handle Entry and insert into linked list // HandleEntry->Signature = SMBIOS_HANDLE_ENTRY_SIGNATURE; HandleEntry->SmbiosHandle = *SmbiosHandle; InsertTailList(&Private->AllocatedHandleListHead, &HandleEntry->Link); InternalRecord = (EFI_SMBIOS_RECORD_HEADER *) (SmbiosEntry + 1); Raw = (VOID *) (InternalRecord + 1); // // Build internal record Header // InternalRecord->Version = EFI_SMBIOS_RECORD_HEADER_VERSION; InternalRecord->HeaderSize = (UINT16) sizeof (EFI_SMBIOS_RECORD_HEADER); InternalRecord->RecordSize = RecordSize; InternalRecord->ProducerHandle = ProducerHandle; InternalRecord->NumberOfStrings = NumberOfStrings; // // Insert record into the internal linked list // SmbiosEntry->Signature = EFI_SMBIOS_ENTRY_SIGNATURE; SmbiosEntry->RecordHeader = InternalRecord; SmbiosEntry->RecordSize = TotalSize; SmbiosEntry->Smbios32BitTable = Smbios32BitTable; SmbiosEntry->Smbios64BitTable = Smbios64BitTable; InsertTailList (&Private->DataListHead, &SmbiosEntry->Link); CopyMem (Raw, Record, StructureSize); ((EFI_SMBIOS_TABLE_HEADER*)Raw)->Handle = *SmbiosHandle; // // Some UEFI drivers (such as network) need some information in SMBIOS table. // Here we create SMBIOS table and publish it in // configuration table, so other UEFI drivers can get SMBIOS table from // configuration table without depending on PI SMBIOS protocol. // SmbiosTableConstruction (Smbios32BitTable, Smbios64BitTable); // // Leave critical section // EfiReleaseLock (&Private->DataLock); return EFI_SUCCESS; }
/***************************************************************************** * FUNCTION * RfL2Callback * DESCRIPTION * Callback routine for L2CAP connections. * PARAMETERS * L2ChannelId [IN] * info [IN] * RETURNS * void *****************************************************************************/ void A2MPMainChannelL2Callback(L2capChannelId L2ChannelId, L2capCallbackParms *info) { A2MP_MAIN_CONN *main_channel; A2MP_CONN *amp_psm_channel; BtRxPacket *rxPacket; U8 i=0; Report(("A2MPMainChannelL2Callback:%d,L2ChannelId:%d", info->event,L2ChannelId)); switch (info->event) { case L2EVENT_DISCONNECTED: break; case L2EVENT_NOTIFY_AMP_PAL_CHANNEL_DISCONNECTED: main_channel = A2MP_FindMainChannel(info->aclLink); if(main_channel !=0) { Report(("The L2ChannelId:%d",L2ChannelId)); Report(("The main_channel->localCid:%d",main_channel->localCid)); if(info->ptrs.NotifyL2CAPA2MPPDisconnected.localCid != main_channel->localCid) // ME_DisconnectPhysicalLink(&info->aclLink->remoteWifiAMP, 0x13); { BTA2MP_PhysicalLinkClose(info->aclLink); } } break; case L2EVENT_NOTIFY_AMP_NORMAL_CHANNEL_DISCONNECTED: main_channel = A2MP_FindMainChannel(info->aclLink); if(main_channel !=0) { Report(("The L2ChannelId:%d",L2ChannelId)); Report(("The main_channel->localCid:%d",main_channel->localCid)); for(i=0; i< BT_AMP_SUPPORTED_LOGICAL_CHANNEL; i++) { Report(("%d,%d,%d,%d",main_channel->remDev->remoteWifiAMP.logicalLink[i].l2cap_id, main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_sate, main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_type, info->ptrs.NotifyL2CAPA2MPPDisconnected.localCid)); if((main_channel->remDev->remoteWifiAMP.logicalLink[i].l2cap_id == info->ptrs.NotifyL2CAPA2MPPDisconnected.localCid) && (main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_sate == BDS_CONNECTED) && (main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_type > 0x01)) { ME_DisconnectLogicalLink(&info->aclLink->remoteWifiAMP, main_channel->remDev->remoteWifiAMP.logicalLink[i].logical_link_handle); break; } } } break; case L2EVENT_AMP_CHANNEL_DETECTED: if(info->status == 0x00) { if(info->aclLink->remoteWifiAMP.detected == 0) { BtA2MPDiscoveryReq discoveryReq; U8 extendedFeatureMask[2]; /* Start AMP discovery procedure. */ info->aclLink->remoteWifiAMP.detected = 1; info->aclLink->remoteWifiAMP.exists = 0; discoveryReq.mtu = 670; discoveryReq.extendedFeatureMaskSize = 0; extendedFeatureMask[0] = 0x00; extendedFeatureMask[1] = 0x00; discoveryReq.extendedFeatureMask = (U8 *)extendedFeatureMask; discoveryReq.extendedFeatureMaskSize = 2; BTA2MP_SendDiscoveryRequest(info->aclLink, &discoveryReq); } else { Report(("Remote A2MP feature detected before, no A2MP operation")); } } break; case L2EVENT_PACKET_HANDLED: { BtA2MPPacket *a2mptxPacket; main_channel = A2MP_FindMainChannel(info->aclLink); if (info->ptrs.packet->flags & BTP_FLAG_LSYSTEM) Assert(0); a2mptxPacket = ContainingRecord(info->ptrs.packet, BtA2MPPacket, btPacket); InsertTailList(&main_channel->freeTtxPacketsList, &(a2mptxPacket->node)); } break; #if L2CAP_FLOW_NON_BASIC_MODE == XA_ENABLED case L2EVENT_FLOW_DATA_IND: Report(("L2EVENT_FLOW_DATA_IND")); main_channel = A2MP_FindMainChannel(info->aclLink); rxPacket = (BtRxPacket *)RemoveHeadList(&main_channel->receivedPacketsList); info->ptrs.data = rxPacket->data; info->dataLen = rxPacket->dataLen; BTA2MP_RecvDataInd(info->aclLink, info->ptrs.data, info->dataLen); rxPacket->dataLen = 0; InsertTailList(&main_channel->rxPacketsBufferList, &rxPacket->node); L2CAP_UpdateSduDataBufferSeq(main_channel->localCid); break; #endif case L2EVENT_LOCKSTEP_CONFIG_REQ: Report(("info->ptrs.lockstepConfigReq.createChannelnitiator:%d",info->ptrs.lockstepConfigReq.createChannelnitiator)); Assert(0); break; case L2EVENT_MOVE_CHANNEL_REQ: /* info->ptrs.moveChannelReq; */ amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId); break; case L2EVENT_MOVE_CHANNEL_RSP: amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId); /* info->ptrs.moveChannelRsp.result; */ break; case L2EVENT_MOVE_CHANNEL_CNF_REQ: amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId); /* info->ptrs.moveChannelCnfReq.result; */ break; case L2EVENT_MOVE_CHANNEL_CNF_RSP: amp_psm_channel = A2MP_FindPSMChannelByCid(L2ChannelId); break; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Searches for files according to specified Mask starting from specified Path. Links all found into the FileListHead. // Returns number of files found. // ULONG FilesFind( PWCHAR Directory, // directory name to search in PWCHAR Mask, // search mask ULONG Flags, // variouse flags PLIST_ENTRY FileListHead // result list of file descriptors ) { ULONG bSize, Found = 0; HANDLE hDir; NTSTATUS ntStatus; UNICODE_STRING uDirectory; OBJECT_ATTRIBUTES oa = {0}; IO_STATUS_BLOCK IoStatus = {0}; PFILE_DIRECTORY_INFORMATION FileInfo, CurInfo; PFILE_DIRECTORY_ENTRY DirEntry; ULONG DirLenBytes = wcslen(Directory) * sizeof(WCHAR); RtlInitUnicodeString(&uDirectory, Directory); InitializeObjectAttributes(&oa, &uDirectory, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, NULL); ntStatus = ZwCreateFile(&hDir, GENERIC_READ, &oa, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (NT_SUCCESS(ntStatus)) { if (FileInfo = MyAllocatePool(PagedPool, PAGE_SIZE)) { do { ntStatus = ZwQueryDirectoryFile(hDir, NULL, NULL, 0, &IoStatus, FileInfo, PAGE_SIZE - sizeof(WCHAR), FileDirectoryInformation, FALSE, NULL, FALSE); if (NT_SUCCESS(ntStatus)) { CurInfo = FileInfo; do { if (CurInfo->FileName[0] != '.') { if (!(CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (Flags & FILES_FIND_DIRECTORIES)) { ULONG NameLen = CurInfo->FileNameLength >> 1; WCHAR z = CurInfo->FileName[NameLen]; CurInfo->FileName[NameLen] = 0; if (__wcswicmp(Mask, (PWCHAR)&CurInfo->FileName)) { if (DirEntry = FilesAlocateDirEntry(DirLenBytes + CurInfo->FileNameLength)) { RtlCopyMemory(&DirEntry->FileInfo, CurInfo, sizeof(FILE_DIRECTORY_INFORMATION)); RtlCopyMemory(&DirEntry->FileInfo.FileName, Directory, DirLenBytes); RtlCopyMemory(&DirEntry->FileInfo.FileName[DirLenBytes >> 1], &CurInfo->FileName, CurInfo->FileNameLength); InsertTailList(FileListHead, &DirEntry->Entry); Found += 1; } } // if (__wcswicmp(Mask, (PWCHAR)&CurInfo->FileName)) CurInfo->FileName[NameLen] = z; } // if (!(CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (Flags & FILES_FIND_DIRECTORIES)) if ((CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (Flags & FILES_SCAN_SUBDIRECTORIES)) { PWCHAR NewDir = MyAllocatePool(PagedPool, DirLenBytes + CurInfo->FileNameLength + 2*sizeof(WCHAR)); if (NewDir) { RtlCopyMemory(NewDir, Directory, DirLenBytes); RtlCopyMemory((PCHAR)NewDir + DirLenBytes, CurInfo->FileName, CurInfo->FileNameLength); NewDir[(DirLenBytes + CurInfo->FileNameLength) >> 1] = '\\'; NewDir[(DirLenBytes + CurInfo->FileNameLength + sizeof(WCHAR)) >> 1] = 0; Found += FilesFind(NewDir, Mask, Flags, FileListHead); MyFreePool(NewDir); } } // if ((CurInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (Flags & FILES_SCAN_SUBDIRECTORIES)) } // if (CurInfo->FileName[0] != '.') if (CurInfo->NextEntryOffset == 0) break; CurInfo = (PFILE_DIRECTORY_INFORMATION)((PCHAR)CurInfo + CurInfo->NextEntryOffset); } while(TRUE); } // if (NT_SUCCESS(ntStatus)) } while(NT_SUCCESS(ntStatus));
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvQueueIrp // Inserts an IRP into the queue if the queue is busy, or sends IRP // to StartIo routine if the queue is not busy. // // Arguments: // IN Queue // An instance of our queue structure // // IN Irp // The IRP to add to the queue // // Return Value: // Status // NTSTATUS testdrvQueueIrp( IN PTESTDRV_QUEUE Queue, IN PIRP Irp ) { NTSTATUS status; KIRQL oldIrql; PTESTDRV_DEVICE_EXTENSION deviceExtension; deviceExtension = (PTESTDRV_DEVICE_EXTENSION)Queue->DeviceObject->DeviceExtension; // grab the queue protection KeAcquireSpinLock(&Queue->QueueLock, &oldIrql); // If the queue has been invalidated, complete the IRP if (Queue->ErrorStatus != STATUS_SUCCESS) { status = Queue->ErrorStatus; // drop the queue protection KeReleaseSpinLock(&Queue->QueueLock, oldIrql); Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // see if the queue is busy if ((Queue->CurrentIrp == NULL) && (Queue->StallCount == 0)) { // mark irp pending since STATUS_PENDING is returned IoMarkIrpPending(Irp); status = STATUS_PENDING; // set the current IRP Queue->CurrentIrp = Irp; // drop the queue protection // raise our IRQL before calling StartIo KeReleaseSpinLockFromDpcLevel(&Queue->QueueLock); // call the user's StartIo routine Queue->StartIoRoutine(Queue->DeviceObject, Queue->CurrentIrp); // drop our IRQL back KeLowerIrql(oldIrql); return status; } // put our queue pointer into the IRP Irp->Tail.Overlay.DriverContext[0] = Queue; // queue the IRP InsertTailList(&Queue->IrpQueue, &Irp->Tail.Overlay.ListEntry); // insert our queue cancel routine into the IRP IoSetCancelRoutine(Irp, testdrvQueueCancelRoutine); // Make sure the IRP was not cancelled before // we inserted our cancel routine if (Irp->Cancel) { // If the IRP was cancelled after we put in our cancel routine we // will get back NULL here and we will let the cancel routine handle // the IRP. If NULL is not returned here then we know the IRP was // cancelled before we inserted the queue cancel routine, and we // need to call our cancel routine to handle the IRP. if (IoSetCancelRoutine(Irp, NULL) != NULL) { RemoveEntryList(&Irp->Tail.Overlay.ListEntry); // drop the queue protection KeReleaseSpinLock(&Queue->QueueLock, oldIrql); // cancel the IRP status = STATUS_CANCELLED; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } } // mark irp pending since STATUS_PENDING is returned IoMarkIrpPending(Irp); status = STATUS_PENDING; // drop the queue protection KeReleaseSpinLock(&Queue->QueueLock, oldIrql); return status; }
VOID LfsWriteLfsRestart ( IN PLFCB Lfcb, IN ULONG ThisRestartSize, IN BOOLEAN WaitForIo ) /*++ Routine Description: This routine puts the Lfs restart area on the queue of operations to write to the file. We do this by allocating a second restart area and attaching it to the Lfcb. We also allocate a buffer control block to use for this write. We look at the WaitForIo boolean to determine whether this thread can perform the I/O. This also indicates whether this thread gives up the Lfcb. Arguments: Lfcb - A pointer to the log file control block for this operation. ThisRestartSize - This is the size to use for the restart area. WaitForIo - Indicates if this thread is to perform the work. Return Value: None. --*/ { PLBCB NewLbcb = NULL; PLFS_RESTART_AREA NewRestart = NULL; PAGED_CODE(); DebugTrace( +1, Dbg, "LfsWriteLfsRestart: Entered\n", 0 ); DebugTrace( 0, Dbg, "Lfcb -> %08lx\n", Lfcb ); DebugTrace( 0, Dbg, "Write Chkdsk -> %04x\n", WriteChkdsk ); DebugTrace( 0, Dbg, "Restart Size -> %08lx\n", ThisRestartSize ); DebugTrace( 0, Dbg, "WaitForIo -> %08lx\n", WaitForIo ); // // We'd absolutely hate for this to happen on a read only volume. // ASSERT(!(FlagOn( Lfcb->Flags, LFCB_READ_ONLY ))); // // Use a try-finally to facilitate cleanup. // try { PLBCB ActiveLbcb; // // We allocate another restart area and // copy the current area into it. Attach the new area to the Lfcb. // LfsAllocateRestartArea( &NewRestart, ThisRestartSize ); // // We allocate a Lbcb structure and update the values to // reflect this restart area. // LfsAllocateLbcb( Lfcb, &NewLbcb ); SetFlag( NewLbcb->LbcbFlags, LBCB_RESTART_LBCB ); // // If this is the second page, then add a page to the offset. // if (!Lfcb->InitialRestartArea) { NewLbcb->FileOffset = Lfcb->LogPageSize + NewLbcb->FileOffset; } (ULONG)NewLbcb->Length = ThisRestartSize; NewLbcb->PageHeader = (PVOID) Lfcb->RestartArea; // // Lets put the current lsn in the Lbcb. // NewLbcb->LastEndLsn = NewLbcb->LastLsn = Lfcb->NextRestartLsn; Lfcb->NextRestartLsn.QuadPart = 1 + Lfcb->NextRestartLsn.QuadPart; // // Copy the existing restart area into the new area. // RtlCopyMemory( NewRestart, Lfcb->RestartArea, ThisRestartSize ); Lfcb->RestartArea = NewRestart; Lfcb->ClientArray = Add2Ptr( NewRestart, Lfcb->ClientArrayOffset, PLFS_CLIENT_RECORD ); NewRestart = NULL; // // Update the Lfcb to indicate that the other restart area // on the disk is to be used. // Lfcb->InitialRestartArea = !Lfcb->InitialRestartArea; // // Add this Lbcb to the end of the workque and flush to that point. // InsertTailList( &Lfcb->LbcbWorkque, &NewLbcb->WorkqueLinks ); // // If we don't support a packed log file then we need to make // sure that all file records written out ahead of this // restart area make it out to disk and we don't add anything // to this page. // if (!FlagOn( Lfcb->Flags, LFCB_PACK_LOG ) && !IsListEmpty( &Lfcb->LbcbActive )) { ActiveLbcb = CONTAINING_RECORD( Lfcb->LbcbActive.Flink, LBCB, ActiveLinks ); if (FlagOn( ActiveLbcb->LbcbFlags, LBCB_NOT_EMPTY )) { RemoveEntryList( &ActiveLbcb->ActiveLinks ); ClearFlag( ActiveLbcb->LbcbFlags, LBCB_ON_ACTIVE_QUEUE ); } } if (WaitForIo) { LfsFlushLbcb( Lfcb, NewLbcb ); } } finally { DebugUnwind( LfsWriteLfsRestart ); if (NewRestart != NULL) { ExFreePool( NewRestart ); } DebugTrace( -1, Dbg, "LfsWriteLfsRestart: Exit\n", 0 ); } return; }
VOID SoundAddIrpToCancellableQ( PLIST_ENTRY QueueHead, PIRP Irp, BOOLEAN Head ) /*++ Routine Description: Add the Irp to the queue and set the cancel routine under the protection of the cancel spin lock. Arguments: QueueHead - the queue to add it to Irp - the Irp Head - if TRUE insert at the head of the queue Return Value: None. --*/ { KIRQL OldIrql; // // Get the cancel spin lock so we can mess with the cancel stuff // IoAcquireCancelSpinLock(&OldIrql); // // Well, it may ALREADY be cancelled! // if (Irp->Cancel) { dprintf2(("Irp already cancelled")); // // Release the cancel spin lock // IoReleaseCancelSpinLock(OldIrql); // // Set status and complete // Irp->IoStatus.Status = STATUS_CANCELLED; IoCompleteRequest(Irp, IO_NO_INCREMENT); return; } // // Set the cancel routine // IoSetCancelRoutine(Irp, SoundRemoveAndComplete); // // Insert it in the queue // if (Head) { InsertHeadList(QueueHead, &Irp->Tail.Overlay.ListEntry); } else { InsertTailList(QueueHead, &Irp->Tail.Overlay.ListEntry); } // // Free the spin lock // IoReleaseCancelSpinLock(OldIrql); }
LONG LoadJobs(VOID) { SCHEDULE Schedule; WCHAR szNameBuffer[JOB_NAME_LENGTH]; DWORD dwNameLength, dwIndex, dwSize; HKEY hJobsKey = NULL, hJobKey = NULL; PJOB pJob = NULL; LONG lError; TRACE("LoadJobs()\n"); lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\Schedule\\Jobs", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hJobsKey, NULL); if (lError != ERROR_SUCCESS) goto done; for (dwIndex = 0; dwIndex < 1000; dwIndex++) { dwNameLength = JOB_NAME_LENGTH; lError = RegEnumKeyEx(hJobsKey, dwIndex, szNameBuffer, &dwNameLength, NULL, NULL, NULL, NULL); if (lError != ERROR_SUCCESS) { lError = ERROR_SUCCESS; break; } TRACE("KeyName: %S\n", szNameBuffer); lError = RegOpenKeyEx(hJobsKey, szNameBuffer, 0, KEY_READ, &hJobKey); if (lError != ERROR_SUCCESS) break; dwSize = sizeof(SCHEDULE); lError = RegQueryValueEx(hJobKey, L"Schedule", NULL, NULL, (PBYTE)&Schedule, &dwSize); if (lError == ERROR_SUCCESS) { dwSize = 0; RegQueryValueEx(hJobKey, L"Command", NULL, NULL, NULL, &dwSize); if (dwSize != 0) { /* Allocate a new job object */ pJob = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JOB) + dwSize - sizeof(WCHAR)); if (pJob == NULL) { lError = ERROR_OUTOFMEMORY; break; } lError = RegQueryValueEx(hJobKey, L"Command", NULL, NULL, (PBYTE)pJob->Command, &dwSize); if (lError != ERROR_SUCCESS) break; wcscpy(pJob->Name, szNameBuffer); pJob->JobTime = Schedule.JobTime; pJob->DaysOfMonth = Schedule.DaysOfMonth; pJob->DaysOfWeek = Schedule.DaysOfWeek; pJob->Flags = Schedule.Flags; /* Acquire the job list lock exclusively */ RtlAcquireResourceExclusive(&JobListLock, TRUE); /* Assign a new job ID */ pJob->JobId = dwNextJobId++; dwJobCount++; // Cancel the start timer /* Append the new job to the job list */ InsertTailList(&JobListHead, &pJob->JobEntry); /* Calculate the next start time */ CalculateNextStartTime(pJob); /* Insert the job into the start list */ InsertJobIntoStartList(&StartListHead, pJob); #if 0 DumpStartList(&StartListHead); #endif // Update the start timer /* Release the job list lock */ RtlReleaseResource(&JobListLock); pJob = NULL; } } RegCloseKey(hJobKey); hJobKey = NULL; } done: if (pJob != NULL) HeapFree(GetProcessHeap(), 0, pJob); if (hJobKey != NULL) RegCloseKey(hJobKey); if (hJobsKey != NULL) RegCloseKey(hJobsKey); return lError; }
NTSTATUS OcObCreateObjectEx( IN POC_OBJECT_TYPE PtrObjectType, IN ULONG AdditionalBufferSize, OUT POC_OBJECT_BODY* PtrPtrObjectBody ) /* This function allocates memory for the object's body and header and initialized the object's header. The object's body is not initialized or zeroed in this function, this is a caller's responsibility! The AdditionalBuffer parameter is used to allocate the buffer at the end of the object, if AdditionalBuffer is not 0x0 then the object must have OcObjectTypeUseStdPoolAllocator set. */ { POC_OBJECT_HEADER PtrObjectHeader; POC_OBJECT_BODY PtrObjectBody; ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL ); ASSERT( TRUE == OcObIsObjectManagerInitialized() ); // // a variable sized object can't be allocated from a look-aside list // if( 0x0 != AdditionalBufferSize && !OcIsFlagOn( PtrObjectType->Flags, OcObjectTypeUseStdPoolAllocator ) ) return STATUS_INVALID_PARAMETER_2; #ifndef USE_STD_ALLOCATOR if( !OcIsFlagOn( PtrObjectType->Flags, OcObjectTypeUseStdPoolAllocator ) ){ //ASSERT( 0x0 == AdditionalBuffer ); PtrObjectHeader = ( POC_OBJECT_HEADER )ExAllocateFromNPagedLookasideList( &PtrObjectType->LookasideList ); } else { #endif//USE_STD_ALLOCATOR PtrObjectHeader = ( POC_OBJECT_HEADER )ExAllocatePoolWithTag( NonPagedPool, PtrObjectType->ObjectsBodySize + sizeof( OC_OBJECT_HEADER ) + AdditionalBufferSize, PtrObjectType->Tag ); #ifndef USE_STD_ALLOCATOR } #endif//USE_STD_ALLOCATOR if( NULL == PtrObjectHeader ) return STATUS_INSUFFICIENT_RESOURCES; // // initialize object's header // RtlZeroMemory( PtrObjectHeader, sizeof( *PtrObjectHeader ) ); PtrObjectHeader->RefCount = 0x1; PtrObjectHeader->ObjectType = PtrObjectType; #if DBG PtrObjectHeader->CommonHeader.Type = OcTypeObject; PtrObjectHeader->CommonHeader.AdditionalBufferSize = AdditionalBufferSize; #endif//DBG // // increment the object type's refrence count // because the new object of this type // has been created // InterlockedIncrement( &PtrObjectType->RefCount ); // // insert the new object into object type's list // if( OcIsFlagOn( PtrObjectType->Flags, OcObjectTypeObjectsInList ) ){ OcObLockObjectType( PtrObjectType ); { InsertTailList( &PtrObjectType->ListHead, &PtrObjectHeader->ListEntry ); } OcObUnlockObjectType( PtrObjectType ); } // // zero the object's body // if( OcIsFlagOn( PtrObjectType->Flags, OcObjectTypeZeroObjectBody ) ){ RtlZeroMemory( OCOB_HEADER_TO_BODY( PtrObjectHeader ), PtrObjectType->ObjectsBodySize + AdditionalBufferSize ); } // // get object's body // PtrObjectBody = OCOB_HEADER_TO_BODY( PtrObjectHeader ); *PtrPtrObjectBody = PtrObjectBody; return STATUS_SUCCESS; }
NTSTATUS NpNotifyChangeDirectory ( IN PROOT_DCB RootDcb, IN PROOT_DCB_CCB Ccb, IN PIRP Irp ) /*++ Routine Description: This is the common routine for doing the notify change directory. Arugments: RootDcb - Supplies the dcb being queried Ccb - Supplies the context of the caller Irp - Supplies the Irp being processed Return Value: NTSTATUS - STATUS_PENDING --*/ { PIO_STACK_LOCATION IrpSp; UNREFERENCED_PARAMETER( Ccb ); PAGED_CODE(); // // Get the current stack location // IrpSp = IoGetCurrentIrpStackLocation( Irp ); DebugTrace(+1, Dbg, "NpNotifyChangeDirectory\n", 0 ); DebugTrace( 0, Dbg, "RootDcb = %08lx", RootDcb); DebugTrace( 0, Dbg, "Ccb = %08lx", Ccb); // // Mark the Irp pending. // IoMarkIrpPending( Irp ); // // BUGBUG - For now, simply place the packet on one of the old queues, // full or partial, based on whether or not changes to anything // other than names were requested. In the future, the filter // must actually be implemented. // if (IrpSp->Parameters.NotifyDirectory.CompletionFilter & ~FILE_NOTIFY_CHANGE_NAME) { InsertTailList( &RootDcb->Specific.Dcb.NotifyFullQueue, &Irp->Tail.Overlay.ListEntry ); } else { InsertTailList( &RootDcb->Specific.Dcb.NotifyPartialQueue, &Irp->Tail.Overlay.ListEntry ); } // // return to our caller a value of status pending // DebugTrace(-1, Dbg, "NpNotifyChangeDirectory -> STATUS_PENDING\n", 0); return STATUS_PENDING; }
/*! \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; } }
BOOLEAN WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, LPWSTR RegistryPath, LPWSTR ImagePath, LPWSTR ServiceName) { PBOOT_DRIVER_LIST_ENTRY BootDriverEntry; NTSTATUS Status; USHORT PathLength; BootDriverEntry = FrLdrHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY), TAG_WLDR_BDE); if (!BootDriverEntry) return FALSE; // DTE will be filled during actual load of the driver BootDriverEntry->LdrEntry = NULL; // Check - if we have a valid ImagePath, if not - we need to build it // like "System32\\Drivers\\blah.sys" if (ImagePath && (ImagePath[0] != 0)) { // Just copy ImagePath to the corresponding field in the structure PathLength = (USHORT)wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL); BootDriverEntry->FilePath.Length = 0; BootDriverEntry->FilePath.MaximumLength = PathLength; BootDriverEntry->FilePath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME); if (!BootDriverEntry->FilePath.Buffer) { FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath); if (!NT_SUCCESS(Status)) { FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME); FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE); return FALSE; } } else { // we have to construct ImagePath ourselves PathLength = (USHORT)wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys"); BootDriverEntry->FilePath.Length = 0; BootDriverEntry->FilePath.MaximumLength = PathLength; BootDriverEntry->FilePath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME); if (!BootDriverEntry->FilePath.Buffer) { FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\"); if (!NT_SUCCESS(Status)) { FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME); FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName); if (!NT_SUCCESS(Status)) { FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME); FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME); return FALSE; } Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys"); if (!NT_SUCCESS(Status)) { FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME); FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME); return FALSE; } } // Add registry path PathLength = (USHORT)(wcslen(RegistryPath) + wcslen(ServiceName))*sizeof(WCHAR) + sizeof(UNICODE_NULL); BootDriverEntry->RegistryPath.Length = 0; BootDriverEntry->RegistryPath.MaximumLength = PathLength; BootDriverEntry->RegistryPath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME); if (!BootDriverEntry->RegistryPath.Buffer) return FALSE; Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath); if (!NT_SUCCESS(Status)) return FALSE; Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName); if (!NT_SUCCESS(Status)) return FALSE; // Insert entry at top of the list InsertTailList(BootDriverListHead, &BootDriverEntry->Link); return TRUE; }
static NTSTATUS ElfCreateEventLogHandle(PLOGHANDLE* LogHandle, PUNICODE_STRING LogName, BOOLEAN Create) { NTSTATUS Status = STATUS_SUCCESS; PLOGHANDLE lpLogHandle; PLOGFILE currentLogFile = NULL; DWORD i, LogsActive; PEVENTSOURCE pEventSource; DPRINT("ElfCreateEventLogHandle(Name: %wZ)\n", LogName); *LogHandle = NULL; i = (LogName->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR); lpLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(LOGHANDLE, szName[i])); if (!lpLogHandle) { DPRINT1("Failed to allocate Heap!\n"); return STATUS_NO_MEMORY; } StringCchCopy(lpLogHandle->szName, i, LogName->Buffer); /* Get the number of Log Files the EventLog service found */ // NOTE: We could just as well loop only once within the list of logs // and retrieve what the code below that calls LogfListItemByIndex, does!! LogsActive = LogfListItemCount(); if (LogsActive == 0) { DPRINT1("EventLog service reports no log files!\n"); Status = STATUS_UNSUCCESSFUL; goto Done; } /* If Creating, default to the Application Log in case we fail, as documented on MSDN */ if (Create) { pEventSource = GetEventSourceByName(LogName->Buffer); DPRINT("EventSource: %p\n", pEventSource); if (pEventSource) { DPRINT("EventSource LogFile: %p\n", pEventSource->LogFile); lpLogHandle->LogFile = pEventSource->LogFile; } else { DPRINT("EventSource LogFile: Application log file\n"); lpLogHandle->LogFile = LogfListItemByName(L"Application"); } DPRINT("LogHandle LogFile: %p\n", lpLogHandle->LogFile); } else { lpLogHandle->LogFile = NULL; for (i = 1; i <= LogsActive; i++) { currentLogFile = LogfListItemByIndex(i); if (_wcsicmp(LogName->Buffer, currentLogFile->LogName) == 0) { lpLogHandle->LogFile = currentLogFile; break; } } /* Use the application log if the desired log does not exist */ if (lpLogHandle->LogFile == NULL) { lpLogHandle->LogFile = LogfListItemByName(L"Application"); if (lpLogHandle->LogFile == NULL) { DPRINT1("Application log is missing!\n"); Status = STATUS_UNSUCCESSFUL; goto Done; } } /* Reset the current record */ lpLogHandle->CurrentRecord = 0; } if (!lpLogHandle->LogFile) Status = STATUS_UNSUCCESSFUL; Done: if (NT_SUCCESS(Status)) { /* Append log handle */ InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry); *LogHandle = lpLogHandle; } else { HeapFree(GetProcessHeap(), 0, lpLogHandle); } return Status; }
VOID CdAddToWorkque ( _Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp ) /*++ Routine Description: This routine is called to acually store the posted Irp to the Fsp workque. Arguments: IrpContext - Pointer to the IrpContext to be queued to the Fsp Irp - I/O Request Packet. Return Value: None. --*/ { PVOLUME_DEVICE_OBJECT Vdo; KIRQL SavedIrql; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); // // Check if this request has an associated file object, and thus volume // device object. // if (IrpSp->FileObject != NULL) { Vdo = CONTAINING_RECORD( IrpSp->DeviceObject, VOLUME_DEVICE_OBJECT, DeviceObject ); // // Check to see if this request should be sent to the overflow // queue. If not, then send it off to an exworker thread. // KeAcquireSpinLock( &Vdo->OverflowQueueSpinLock, &SavedIrql ); if (Vdo->PostedRequestCount > FSP_PER_DEVICE_THRESHOLD) { // // We cannot currently respond to this IRP so we'll just enqueue it // to the overflow queue on the volume. // InsertTailList( &Vdo->OverflowQueue, &IrpContext->WorkQueueItem.List ); Vdo->OverflowQueueCount += 1; KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql ); return; } else { // // We are going to send this Irp to an ex worker thread so up // the count. // Vdo->PostedRequestCount += 1; KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql ); } } // // Send it off..... // #pragma prefast(suppress:28155, "the function prototype is correct") ExInitializeWorkItem( &IrpContext->WorkQueueItem, CdFspDispatch, IrpContext ); #pragma prefast(suppress: 28159, "prefast believes this routine is obsolete, but it is ok for CDFS to continue using it") ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue ); return; }
NTSTATUS NTAPI LdrpLoadDll( IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines ) { PPEB Peb; PTEB Teb; NTSTATUS st; PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; PWSTR ActualDllName; PWCH p, pp; UNICODE_STRING ActualDllNameStr; BOOLEAN Wx86KnownDll = FALSE; WCHAR FreeBuffer[266]; Peb = NtCurrentPeb(); Teb = NtCurrentTeb(); st = STATUS_SUCCESS; try { // // Grab Peb lock and Snap All Links to specified DLL // if ( LdrpInLdrInit == FALSE ) { RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); } #if defined (WX86) if (Teb->Wx86Thread.UseKnownWx86Dll) { Wx86KnownDll = Teb->Wx86Thread.UseKnownWx86Dll; Teb->Wx86Thread.UseKnownWx86Dll = FALSE; } #endif p = DllName->Buffer; pp = NULL; while (*p) { if (*p++ == (WCHAR)'.') { // // pp will point to first character after last '.' // pp = p; } } ActualDllName = FreeBuffer; if ( DllName->Length >= sizeof(FreeBuffer)) { return STATUS_NAME_TOO_LONG; } RtlMoveMemory(ActualDllName, DllName->Buffer, DllName->Length); if (!pp || *pp == (WCHAR)'\\') { // // No extension found (just ..\) // if ( DllName->Length+10 >= sizeof(FreeBuffer) ) { return STATUS_NAME_TOO_LONG; } RtlMoveMemory((PCHAR)ActualDllName+DllName->Length, DLLEXTENSION, 10); } else { ActualDllName[DllName->Length >> 1] = UNICODE_NULL; } if (ShowSnaps) { DbgPrint("LDR: LdrLoadDll, loading %ws from %ws\n", ActualDllName, ARGUMENT_PRESENT(DllPath) ? DllPath : L"" ); } RtlInitUnicodeString(&ActualDllNameStr,ActualDllName); ActualDllNameStr.MaximumLength = sizeof(FreeBuffer); if (!LdrpCheckForLoadedDll( DllPath, &ActualDllNameStr, FALSE, Wx86KnownDll, &LdrDataTableEntry ) ) { st = LdrpMapDll(DllPath, ActualDllName, DllCharacteristics, FALSE, Wx86KnownDll, &LdrDataTableEntry ); if (!NT_SUCCESS(st)) { return st; } if (ARGUMENT_PRESENT( DllCharacteristics ) && *DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE ) { LdrDataTableEntry->EntryPoint = 0; LdrDataTableEntry->Flags &= ~LDRP_IMAGE_DLL; } // // and walk the import descriptor. // if (LdrDataTableEntry->Flags & LDRP_IMAGE_DLL) { try { st = LdrpWalkImportDescriptor( DllPath, LdrDataTableEntry ); } except(EXCEPTION_EXECUTE_HANDLER) { st = GetExceptionCode(); } if ( LdrDataTableEntry->LoadCount != 0xffff ) { LdrDataTableEntry->LoadCount++; } LdrpReferenceLoadedDll(LdrDataTableEntry); if (!NT_SUCCESS(st)) { LdrDataTableEntry->EntryPoint = NULL; InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, &LdrDataTableEntry->InInitializationOrderLinks); LdrpClearLoadInProgress(); LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); return st; } } else { if ( LdrDataTableEntry->LoadCount != 0xffff ) { LdrDataTableEntry->LoadCount++; } } // // Add init routine to list // InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, &LdrDataTableEntry->InInitializationOrderLinks); // // If the loader data base is not fully setup, this load was because // of a forwarder in the static load set. Can't run init routines // yet because the load counts are NOT set // if ( RunInitRoutines && LdrpLdrDatabaseIsSetup ) { try { st = LdrpRunInitializeRoutines(NULL); if ( !NT_SUCCESS(st) ) { LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); } } except( EXCEPTION_EXECUTE_HANDLER ) { LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); return GetExceptionCode(); } } else {
static NTSTATUS OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl, OVS_TUNNEL_PENDED_PACKET *packet) { NTSTATUS status = STATUS_SUCCESS; OvsIPv4TunnelKey tunnelKey; NET_BUFFER *pNb; ULONG sendCompleteFlags = 0; BOOLEAN dispatch; PNDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO fwdDetail; LOCK_STATE_EX lockState, dpLockState; LIST_ENTRY missedPackets; OvsCompletionList completionList; KIRQL irql; ULONG SendFlags = NDIS_SEND_FLAGS_SWITCH_DESTINATION_GROUP; OVS_DATAPATH *datapath = NULL; ASSERT(gOvsSwitchContext); datapath = &gOvsSwitchContext->datapath; /* Fill the tunnel key */ status = OvsSlowPathDecapVxlan(pNbl, &tunnelKey); if(!NT_SUCCESS(status)) { goto dropit; } pNb = NET_BUFFER_LIST_FIRST_NB(pNbl); NdisAdvanceNetBufferDataStart(pNb, packet->transportHeaderSize + packet->ipHeaderSize + sizeof(VXLANHdr), FALSE, NULL); /* Most likely (always) dispatch irql */ irql = KeGetCurrentIrql(); /* dispatch is used for datapath lock as well */ dispatch = (irql == DISPATCH_LEVEL) ? NDIS_RWL_AT_DISPATCH_LEVEL : 0; if (dispatch) { sendCompleteFlags |= NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL; } InitializeListHead(&missedPackets); OvsInitCompletionList(&completionList, gOvsSwitchContext, sendCompleteFlags); { POVS_VPORT_ENTRY vport; UINT32 portNo; OVS_PACKET_HDR_INFO layers; OvsFlowKey key; UINT64 hash; PNET_BUFFER curNb; OvsFlow *flow; fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(pNbl); /* * XXX WFP packets contain a single NBL structure. * Reassembeled packet "may" have multiple NBs, however, a simple test shows * that the packet still has a single NB (after reassemble) * We still need to check if the Ethernet header of the innet packet is in a single MD */ curNb = NET_BUFFER_LIST_FIRST_NB(pNbl); ASSERT(curNb->Next == NULL); NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState, dispatch); /* Lock the flowtable for the duration of accessing the flow */ OvsAcquireDatapathRead(datapath, &dpLockState, NDIS_RWL_AT_DISPATCH_LEVEL); SendFlags |= NDIS_SEND_FLAGS_DISPATCH_LEVEL; vport = OvsFindTunnelVportByDstPort(gOvsSwitchContext, htons(tunnelKey.dst_port), OVS_VPORT_TYPE_VXLAN); if (vport == NULL){ status = STATUS_UNSUCCESSFUL; goto unlockAndDrop; } ASSERT(vport->ovsType == OVS_VPORT_TYPE_VXLAN); portNo = vport->portNo; status = OvsExtractFlow(pNbl, portNo, &key, &layers, &tunnelKey); if (status != NDIS_STATUS_SUCCESS) { goto unlockAndDrop; } flow = OvsLookupFlow(datapath, &key, &hash, FALSE); if (flow) { OvsFlowUsed(flow, pNbl, &layers); datapath->hits++; OvsActionsExecute(gOvsSwitchContext, &completionList, pNbl, portNo, SendFlags, &key, &hash, &layers, flow->actions, flow->actionsLen); OvsReleaseDatapath(datapath, &dpLockState); } else { POVS_PACKET_QUEUE_ELEM elem; datapath->misses++; elem = OvsCreateQueueNlPacket(NULL, 0, OVS_PACKET_CMD_MISS, portNo, &key, pNbl, curNb, TRUE, &layers); if (elem) { /* Complete the packet since it was copied to user buffer. */ InsertTailList(&missedPackets, &elem->link); OvsQueuePackets(&missedPackets, 1); } else { status = STATUS_INSUFFICIENT_RESOURCES; } goto unlockAndDrop; } NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState); } return status; unlockAndDrop: OvsReleaseDatapath(datapath, &dpLockState); NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState); dropit: pNbl = OvsCompleteNBL(gOvsSwitchContext, pNbl, TRUE); ASSERT(pNbl == NULL); return status; }
VOID CdQueueClose ( _In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ ULONG UserReference, _In_ BOOLEAN DelayedClose ) /*++ Routine Description: This routine is called to queue a request to either the async or delayed close queue. For the delayed queue we need to allocate a smaller structure to contain the information about the file object. We do that so we don't put the larger IrpContext structures into this long lived queue. If we can allocate this structure then we put this on the async queue instead. Arguments: Fcb - Fcb for this file object. UserReference - Number of user references for this file object. This is zero for an internal stream. DelayedClose - Indicates whether this should go on the async or delayed close queue. Return Value: None --*/ { PIRP_CONTEXT_LITE IrpContextLite = NULL; BOOLEAN StartWorker = FALSE; PAGED_CODE(); ASSERT_IRP_CONTEXT( IrpContext ); ASSERT_FCB( Fcb ); // // Start with the delayed queue request. We can move this to the async // queue if there is an allocation failure. // if (DelayedClose) { // // Try to allocate non-paged pool for the IRP_CONTEXT_LITE. // IrpContextLite = CdCreateIrpContextLite( IrpContext ); } // // We want to clear the top level context in this thread if // necessary. Call our cleanup routine to do the work. // SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); CdCleanupIrpContext( IrpContext, TRUE ); // // Synchronize with the CdData lock. // CdLockCdData(); // // If we have an IrpContext then put the request on the delayed close queue. // if (IrpContextLite != NULL) { // // Initialize the IrpContextLite. // IrpContextLite->NodeTypeCode = CDFS_NTC_IRP_CONTEXT_LITE; IrpContextLite->NodeByteSize = sizeof( IRP_CONTEXT_LITE ); IrpContextLite->Fcb = Fcb; IrpContextLite->UserReference = UserReference; IrpContextLite->RealDevice = IrpContext->RealDevice; // // Add this to the delayed close list and increment // the count. // InsertTailList( &CdData.DelayedCloseQueue, &IrpContextLite->DelayedCloseLinks ); CdData.DelayedCloseCount += 1; // // If we are above our threshold then start the delayed // close operation. // if (CdData.DelayedCloseCount > CdData.MaxDelayedCloseCount) { CdData.ReduceDelayedClose = TRUE; if (!CdData.FspCloseActive) { CdData.FspCloseActive = TRUE; StartWorker = TRUE; } } // // Unlock the CdData. // CdUnlockCdData(); // // Cleanup the IrpContext. // CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); // // Otherwise drop into the async case below. // } else { // // Store the information about the file object into the IrpContext. // IrpContext->Irp = (PIRP) Fcb; IrpContext->ExceptionStatus = (NTSTATUS) UserReference; // // Add this to the async close list and increment the count. // InsertTailList( &CdData.AsyncCloseQueue, &IrpContext->WorkQueueItem.List ); CdData.AsyncCloseCount += 1; // // Remember to start the Fsp close thread if not currently started. // if (!CdData.FspCloseActive) { CdData.FspCloseActive = TRUE; StartWorker = TRUE; } // // Unlock the CdData. // CdUnlockCdData(); } // // Start the FspClose thread if we need to. // if (StartWorker) { IoQueueWorkItem( CdData.CloseItem, CdCloseWorker, CriticalWorkQueue, NULL ); } // // Return to our caller. // return; }
/** This function create a currently loaded Boot Option from the BMM. It then appends this Boot Option to the end of the "BootOrder" list. It also append this Boot Opotion to the end of BootOptionMenu. @param CallbackData The BMM context data. @param NvRamMap The file explorer formset internal state. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateBootOption ( IN BMM_CALLBACK_DATA *CallbackData, IN FILE_EXPLORER_NV_DATA *NvRamMap ) { UINT16 *BootOrderList; UINT16 *NewBootOrderList; UINTN BootOrderListSize; UINT16 BootString[10]; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; UINT16 Index; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; OptionalDataExist = FALSE; Index = BOpt_GetBootOptionNumber () ; UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); if (NvRamMap->BootDescriptionData[0] == 0x0000) { StrCpyS ( NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString ); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->BootDescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (NvRamMap->BootOptionalData[0] != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (NvRamMap->BootOptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, NvRamMap->BootDescriptionData, StrSize (NvRamMap->BootDescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (NvRamMap->BootDescriptionData) ); Ptr += StrSize (NvRamMap->BootDescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionStrDepository ); NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionHelpStrDepository ); NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem (Ptr, NvRamMap->BootOptionalData, StrSize (NvRamMap->BootOptionalData)); } Status = gRT->SetVariable ( BootString, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BufferSize, Buffer ); if (!EFI_ERROR (Status)) { BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); ASSERT (BootOrderList != NULL); NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16)); ASSERT (NewBootOrderList != NULL); CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize); NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index; if (BootOrderList != NULL) { FreePool (BootOrderList); } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BootOrderListSize + sizeof (UINT16), NewBootOrderList ); if (!EFI_ERROR (Status)) { FreePool (NewBootOrderList); NewBootOrderList = NULL; InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); BootOptionMenu.MenuNumber++; // // Update "change driver order" page used data, append the new add driver // option at the end. // Index = 0; while (CallbackData->BmmFakeNvData.BootOptionOrder[Index] != 0) { Index++; } CallbackData->BmmFakeNvData.BootOptionOrder[Index] = (UINT32) (NewMenuEntry->OptionNumber + 1); NvRamMap->BootDescriptionData[0] = 0x0000; NvRamMap->BootOptionalData[0] = 0x0000; } } return EFI_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvFlushList // Cancels all IRPs in the list, or all IRPs in the list related to a // particular open handle. // // Arguments: // IN List // An instance of our list structure // // IN FileObject // If NULL all IRPs in list are cancelled, if non-NULL then all // IRPs related to this file object are cancelled. // // Return Value: // none // VOID testdrvFlushList( IN PTESTDRV_LIST List, IN PFILE_OBJECT FileObject ) { PLIST_ENTRY entry; PLIST_ENTRY nextEntry; PIRP irp; PIO_STACK_LOCATION irpStack; KIRQL oldIrql; LIST_ENTRY cancelList; // initialize our cancel list InitializeListHead(&cancelList); // grab the list protection KeAcquireSpinLock(&List->ListLock, &oldIrql); // Look at the first entry in the list entry = List->IrpList.Flink; while (entry != &List->IrpList) { // get the next list entry nextEntry = entry->Flink; // Get the IRP from the entry irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry); ASSERT(irp->Type == IO_TYPE_IRP); // Determine if we need to pull out of list if (FileObject != NULL) { // get the current IRP stack location from the IRP irpStack = IoGetCurrentIrpStackLocation(irp); if (irpStack->FileObject != FileObject) { // go to the next entry entry = nextEntry; // We are not flushing this IRP continue; } } // Attempt to cancel the IRP if (IoSetCancelRoutine(irp, NULL) == NULL) { // go to the next entry entry = nextEntry; // cancel routine already has this IRP, // just go on continue; } // pull the IRP from the list RemoveEntryList(entry); InsertTailList(&cancelList, entry); // go to the next entry entry = nextEntry; } // drop the list protection KeReleaseSpinLock(&List->ListLock, oldIrql); // Now clear out our cancel list while (!IsListEmpty(&cancelList)) { // Get the first entry on the list entry = RemoveHeadList(&cancelList); // Get the IRP for that entry irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry); // Cancel the IRP irp->IoStatus.Status = STATUS_CANCELLED; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); } return; }
NTSTATUS Bus_Internal_IoCtl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION irpStack; NTSTATUS status; ULONG inlen; PPDO_DEVICE_DATA pdoData; PVOID buffer; PCOMMON_DEVICE_DATA commonData; commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); if (commonData->IsFDO) { Irp->IoStatus.Status = status = STATUS_INVALID_DEVICE_REQUEST; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } pdoData = (PPDO_DEVICE_DATA) DeviceObject->DeviceExtension; if (pdoData->Present == FALSE) { Irp->IoStatus.Status = status = STATUS_DEVICE_NOT_CONNECTED; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } buffer = Irp->AssociatedIrp.SystemBuffer; inlen = irpStack->Parameters.DeviceIoControl.InputBufferLength; status = STATUS_INVALID_PARAMETER; switch(irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_INTERNAL_USB_SUBMIT_URB: { PURB pHxp = (PURB) irpStack->Parameters.Others.Argument1; switch (pHxp->UrbHeader.Function) { case URB_FUNCTION_CONTROL_TRANSFER : { #if DBG struct _URB_CONTROL_TRANSFER* pTransfer = &pHxp->UrbControlTransfer; Bus_KdPrint(("URB_FUNCTION_CONTROL_TRANSFER : Function %X\n", pTransfer->Hdr.Function)); Bus_KdPrint(("URB_FUNCTION_CONTROL_TRANSFER : Handle %p, Flags %X, Length %d\n", pTransfer->PipeHandle, pTransfer->TransferFlags, pTransfer->TransferBufferLength)); Bus_KdPrint(("URB_FUNCTION_CONTROL_TRANSFER : Setup [%02X %02X %02X %02X %02X %02X %02X %02X]\n", (int) pTransfer->SetupPacket[0], (int) pTransfer->SetupPacket[1], (int) pTransfer->SetupPacket[2], (int) pTransfer->SetupPacket[3], (int) pTransfer->SetupPacket[4], (int) pTransfer->SetupPacket[5], (int) pTransfer->SetupPacket[6], (int) pTransfer->SetupPacket[7])); #endif status = STATUS_UNSUCCESSFUL; } break; case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER : { struct _URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer = &pHxp->UrbBulkOrInterruptTransfer; if (pdoData->DevicePnPState != Started) { status = STATUS_UNSUCCESSFUL; } else if (pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN) { KIRQL PrevIrql; UCHAR Pipe = pTransfer->PipeHandle == (USBD_PIPE_HANDLE) 0xFFFF0081 ? 0x81 : 0x83; if (Pipe == 0x81) { status = STATUS_PENDING; IoMarkIrpPending(Irp); KeAcquireSpinLock(&pdoData->PendingQueueLock, &PrevIrql); { IoSetCancelRoutine(Irp, Bus_CancelIrp); if (Irp->Cancel == TRUE) { IoSetCancelRoutine(Irp, NULL); KeReleaseSpinLock(&pdoData->PendingQueueLock, PrevIrql); Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); } else { PPENDING_IRP le = ExAllocateFromNPagedLookasideList(&g_LookAside); le->Irp = Irp; InsertTailList(&pdoData->PendingQueue, &le->Link); KeReleaseSpinLock(&pdoData->PendingQueueLock, PrevIrql); } } } else { status = STATUS_PENDING; IoMarkIrpPending(Irp); KeAcquireSpinLock(&pdoData->PendingQueueLock, &PrevIrql); { IoSetCancelRoutine(Irp, Bus_CancelIrp); if (Irp->Cancel == TRUE) { IoSetCancelRoutine(Irp, NULL); KeReleaseSpinLock(&pdoData->PendingQueueLock, PrevIrql); Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); } else { PPENDING_IRP le = ExAllocateFromNPagedLookasideList(&g_LookAside); le->Irp = Irp; InsertTailList(&pdoData->HoldingQueue, &le->Link); KeReleaseSpinLock(&pdoData->PendingQueueLock, PrevIrql); } } } } else { Bus_KdPrint(("<< URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER : Handle %p, Flags %X, Length %d\n", pTransfer->PipeHandle, pTransfer->TransferFlags, pTransfer->TransferBufferLength)); status = STATUS_SUCCESS; #if DBG if (pTransfer->TransferBufferLength == LEDSET_SIZE) // Led { UCHAR* Buffer = pTransfer->TransferBuffer; Bus_KdPrint(("-- Buffer : %02X %02X %02X", Buffer[0], Buffer[1], Buffer[2])); } #endif if (pTransfer->TransferBufferLength == RUMBLE_SIZE) // Rumble { UCHAR* Buffer = pTransfer->TransferBuffer; ULONG Index; Bus_KdPrint(("-- Buffer : %02X %02X %02X %02X %02X %02X %02X %02X", Buffer[0], Buffer[1], Buffer[2], Buffer[3], Buffer[4], Buffer[5], Buffer[6], Buffer[7])); for (Index = 0; Index < pTransfer->TransferBufferLength; Index++) { pdoData->Rumble[Index] = Buffer[Index]; } } } } break; case URB_FUNCTION_SELECT_CONFIGURATION : { PUSBD_INTERFACE_INFORMATION pInfo; pInfo = &pHxp->UrbSelectConfiguration.Interface; Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : TotalLength %d, Size %d\n", pHxp->UrbHeader.Length, CONFIGURATION_SIZE)); if (pHxp->UrbHeader.Length == sizeof(struct _URB_SELECT_CONFIGURATION)) { Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : NULL ConfigurationDescriptor\n")); status = STATUS_SUCCESS; break; } if (pHxp->UrbHeader.Length < CONFIGURATION_SIZE) { Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : Invalid ConfigurationDescriptor\n")); status = STATUS_INVALID_PARAMETER; break; } status = STATUS_SUCCESS; Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : Length %d, Interface %d, Alternate %d, Pipes %d\n", (int) pInfo->Length, (int) pInfo->InterfaceNumber, (int) pInfo->AlternateSetting, pInfo->NumberOfPipes)); pInfo->Class = 0xFF; pInfo->SubClass = 0x5D; pInfo->Protocol = 0x01; pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE) 0xFFFF0000; pInfo->Pipes[0].MaximumTransferSize = 0x00400000; pInfo->Pipes[0].MaximumPacketSize = 0x20; pInfo->Pipes[0].EndpointAddress = 0x81; pInfo->Pipes[0].Interval = 0x04; pInfo->Pipes[0].PipeType = 0x03; pInfo->Pipes[0].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0081; pInfo->Pipes[0].PipeFlags = 0x00; pInfo->Pipes[1].MaximumTransferSize = 0x00400000; pInfo->Pipes[1].MaximumPacketSize = 0x20; pInfo->Pipes[1].EndpointAddress = 0x01; pInfo->Pipes[1].Interval = 0x08; pInfo->Pipes[1].PipeType = 0x03; pInfo->Pipes[1].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0001; pInfo->Pipes[1].PipeFlags = 0x00; pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR) pInfo + pInfo->Length); Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : Length %d, Interface %d, Alternate %d, Pipes %d\n", (int) pInfo->Length, (int) pInfo->InterfaceNumber, (int) pInfo->AlternateSetting, pInfo->NumberOfPipes)); pInfo->Class = 0xFF; pInfo->SubClass = 0x5D; pInfo->Protocol = 0x03; pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE) 0xFFFF0000; pInfo->Pipes[0].MaximumTransferSize = 0x00400000; pInfo->Pipes[0].MaximumPacketSize = 0x20; pInfo->Pipes[0].EndpointAddress = 0x82; pInfo->Pipes[0].Interval = 0x04; pInfo->Pipes[0].PipeType = 0x03; pInfo->Pipes[0].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0082; pInfo->Pipes[0].PipeFlags = 0x00; pInfo->Pipes[1].MaximumTransferSize = 0x00400000; pInfo->Pipes[1].MaximumPacketSize = 0x20; pInfo->Pipes[1].EndpointAddress = 0x02; pInfo->Pipes[1].Interval = 0x08; pInfo->Pipes[1].PipeType = 0x03; pInfo->Pipes[1].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0002; pInfo->Pipes[1].PipeFlags = 0x00; pInfo->Pipes[2].MaximumTransferSize = 0x00400000; pInfo->Pipes[2].MaximumPacketSize = 0x20; pInfo->Pipes[2].EndpointAddress = 0x83; pInfo->Pipes[2].Interval = 0x08; pInfo->Pipes[2].PipeType = 0x03; pInfo->Pipes[2].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0083; pInfo->Pipes[2].PipeFlags = 0x00; pInfo->Pipes[3].MaximumTransferSize = 0x00400000; pInfo->Pipes[3].MaximumPacketSize = 0x20; pInfo->Pipes[3].EndpointAddress = 0x03; pInfo->Pipes[3].Interval = 0x08; pInfo->Pipes[3].PipeType = 0x03; pInfo->Pipes[3].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0003; pInfo->Pipes[3].PipeFlags = 0x00; pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR) pInfo + pInfo->Length); Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : Length %d, Interface %d, Alternate %d, Pipes %d\n", (int) pInfo->Length, (int) pInfo->InterfaceNumber, (int) pInfo->AlternateSetting, pInfo->NumberOfPipes)); pInfo->Class = 0xFF; pInfo->SubClass = 0x5D; pInfo->Protocol = 0x02; pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE) 0xFFFF0000; pInfo->Pipes[0].MaximumTransferSize = 0x00400000; pInfo->Pipes[0].MaximumPacketSize = 0x20; pInfo->Pipes[0].EndpointAddress = 0x84; pInfo->Pipes[0].Interval = 0x04; pInfo->Pipes[0].PipeType = 0x03; pInfo->Pipes[0].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0084; pInfo->Pipes[0].PipeFlags = 0x00; pInfo = (PUSBD_INTERFACE_INFORMATION)((PCHAR) pInfo + pInfo->Length); Bus_KdPrint(("URB_FUNCTION_SELECT_CONFIGURATION : Length %d, Interface %d, Alternate %d, Pipes %d\n", (int) pInfo->Length, (int) pInfo->InterfaceNumber, (int) pInfo->AlternateSetting, pInfo->NumberOfPipes)); pInfo->Class = 0xFF; pInfo->SubClass = 0xFD; pInfo->Protocol = 0x13; pInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE) 0xFFFF0000; } break; case URB_FUNCTION_SELECT_INTERFACE : { PUSBD_INTERFACE_INFORMATION pInfo = &pHxp->UrbSelectInterface.Interface; Bus_KdPrint(("URB_FUNCTION_SELECT_INTERFACE : Length %d, Interface %d, Alternate %d, Pipes %d\n", (int) pInfo->Length, (int) pInfo->InterfaceNumber, (int) pInfo->AlternateSetting, pInfo->NumberOfPipes)); Bus_KdPrint(("URB_FUNCTION_SELECT_INTERFACE : Class %d, SubClass %d, Protocol %d\n", (int) pInfo->Class, (int) pInfo->SubClass, (int) pInfo->Protocol)); if (pInfo->InterfaceNumber == 1) { status = STATUS_SUCCESS; pInfo[0].Class = 0xFF; pInfo[0].SubClass = 0x5D; pInfo[0].Protocol = 0x03; pInfo[0].NumberOfPipes = 0x04; pInfo[0].InterfaceHandle = (USBD_INTERFACE_HANDLE) 0xFFFF0000; pInfo[0].Pipes[0].MaximumTransferSize = 0x00400000; pInfo[0].Pipes[0].MaximumPacketSize = 0x20; pInfo[0].Pipes[0].EndpointAddress = 0x82; pInfo[0].Pipes[0].Interval = 0x04; pInfo[0].Pipes[0].PipeType = 0x03; pInfo[0].Pipes[0].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0082; pInfo[0].Pipes[0].PipeFlags = 0x00; pInfo[0].Pipes[1].MaximumTransferSize = 0x00400000; pInfo[0].Pipes[1].MaximumPacketSize = 0x20; pInfo[0].Pipes[1].EndpointAddress = 0x02; pInfo[0].Pipes[1].Interval = 0x08; pInfo[0].Pipes[1].PipeType = 0x03; pInfo[0].Pipes[1].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0002; pInfo[0].Pipes[1].PipeFlags = 0x00; pInfo[0].Pipes[2].MaximumTransferSize = 0x00400000; pInfo[0].Pipes[2].MaximumPacketSize = 0x20; pInfo[0].Pipes[2].EndpointAddress = 0x83; pInfo[0].Pipes[2].Interval = 0x08; pInfo[0].Pipes[2].PipeType = 0x03; pInfo[0].Pipes[2].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0083; pInfo[0].Pipes[2].PipeFlags = 0x00; pInfo[0].Pipes[3].MaximumTransferSize = 0x00400000; pInfo[0].Pipes[3].MaximumPacketSize = 0x20; pInfo[0].Pipes[3].EndpointAddress = 0x03; pInfo[0].Pipes[3].Interval = 0x08; pInfo[0].Pipes[3].PipeType = 0x03; pInfo[0].Pipes[3].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0003; pInfo[0].Pipes[3].PipeFlags = 0x00; } else if (pInfo->InterfaceNumber == 2) { status = STATUS_SUCCESS; pInfo[0].Class = 0xFF; pInfo[0].SubClass = 0x5D; pInfo[0].Protocol = 0x02; pInfo[0].NumberOfPipes = 0x01; pInfo[0].InterfaceHandle = (USBD_INTERFACE_HANDLE) 0xFFFF0000; pInfo[0].Pipes[0].MaximumTransferSize = 0x00400000; pInfo[0].Pipes[0].MaximumPacketSize = 0x20; pInfo[0].Pipes[0].EndpointAddress = 0x84; pInfo[0].Pipes[0].Interval = 0x04; pInfo[0].Pipes[0].PipeType = 0x03; pInfo[0].Pipes[0].PipeHandle = (USBD_PIPE_HANDLE) 0xFFFF0084; pInfo[0].Pipes[0].PipeFlags = 0x00; } } break; case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE : Bus_KdPrint(("Descriptor : Type %d, Index %d\n", pHxp->UrbControlDescriptorRequest.DescriptorType, pHxp->UrbControlDescriptorRequest.Index)); switch (pHxp->UrbControlDescriptorRequest.DescriptorType) { case USB_DEVICE_DESCRIPTOR_TYPE: Bus_KdPrint(("USB_DEVICE_DESCRIPTOR_TYPE : Buffer %p, Length %d\n", pHxp->UrbControlDescriptorRequest.TransferBuffer, pHxp->UrbControlDescriptorRequest.TransferBufferLength)); { PUSB_DEVICE_DESCRIPTOR pDescriptor = (PUSB_DEVICE_DESCRIPTOR) pHxp->UrbControlDescriptorRequest.TransferBuffer; status = STATUS_SUCCESS; pDescriptor->bLength = 0x12; pDescriptor->bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE; pDescriptor->bcdUSB = 0x0200; pDescriptor->bDeviceClass = 0xFF; pDescriptor->bDeviceSubClass = 0xFF; pDescriptor->bDeviceProtocol = 0xFF; pDescriptor->bMaxPacketSize0 = 0x08; pDescriptor->idVendor = 0x045E; pDescriptor->idProduct = 0x028E; pDescriptor->bcdDevice = 0x0114; pDescriptor->iManufacturer = 0x01; pDescriptor->iProduct = 0x02; pDescriptor->iSerialNumber = 0x03; pDescriptor->bNumConfigurations = 0x01; } break; case USB_CONFIGURATION_DESCRIPTOR_TYPE: Bus_KdPrint(("USB_CONFIGURATION_DESCRIPTOR_TYPE : Buffer %p, Length %d\n", pHxp->UrbControlDescriptorRequest.TransferBuffer, pHxp->UrbControlDescriptorRequest.TransferBufferLength)); { UCHAR Descriptor_Data[DESCRIPTOR_SIZE] = { 0x09, 0x02, 0x99, 0x00, 0x04, 0x01, 0x00, 0xA0, 0xFA, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x5D, 0x01, 0x00, 0x11, 0x21, 0x00, 0x01, 0x01, 0x25, 0x81, 0x14, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x08, 0x00, 0x00, 0x07, 0x05, 0x81, 0x03, 0x20, 0x00, 0x04, 0x07, 0x05, 0x01, 0x03, 0x20, 0x00, 0x08, 0x09, 0x04, 0x01, 0x00, 0x04, 0xFF, 0x5D, 0x03, 0x00, 0x1B, 0x21, 0x00, 0x01, 0x01, 0x01, 0x82, 0x40, 0x01, 0x02, 0x20, 0x16, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x05, 0x82, 0x03, 0x20, 0x00, 0x02, 0x07, 0x05, 0x02, 0x03, 0x20, 0x00, 0x04, 0x07, 0x05, 0x83, 0x03, 0x20, 0x00, 0x40, 0x07, 0x05, 0x03, 0x03, 0x20, 0x00, 0x10, 0x09, 0x04, 0x02, 0x00, 0x01, 0xFF, 0x5D, 0x02, 0x00, 0x09, 0x21, 0x00, 0x01, 0x01, 0x22, 0x84, 0x07, 0x00, 0x07, 0x05, 0x84, 0x03, 0x20, 0x00, 0x10, 0x09, 0x04, 0x03, 0x00, 0x00, 0xFF, 0xFD, 0x13, 0x04, 0x06, 0x41, 0x00, 0x01, 0x01, 0x03 }; PUSB_CONFIGURATION_DESCRIPTOR pDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) pHxp->UrbControlDescriptorRequest.TransferBuffer; status = STATUS_SUCCESS; pDescriptor->bLength = 0x09; pDescriptor->bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE; pDescriptor->wTotalLength = DESCRIPTOR_SIZE; pDescriptor->bNumInterfaces = 0x04; pDescriptor->bConfigurationValue = 0x01; pDescriptor->iConfiguration = 0x00; pDescriptor->bmAttributes = 0xA0; pDescriptor->MaxPower = 0xFA; if (pHxp->UrbControlDescriptorRequest.TransferBufferLength >= DESCRIPTOR_SIZE) { UCHAR* Buffer = pHxp->UrbControlDescriptorRequest.TransferBuffer; int Index; for (Index = 0; Index < DESCRIPTOR_SIZE; Index++) { Buffer[Index] = Descriptor_Data[Index]; } } } break; case USB_STRING_DESCRIPTOR_TYPE: Bus_KdPrint(("USB_STRING_DESCRIPTOR_TYPE : Index %d, Buffer %p, Length %d\n", pHxp->UrbControlDescriptorRequest.Index, pHxp->UrbControlDescriptorRequest.TransferBuffer, pHxp->UrbControlDescriptorRequest.TransferBufferLength)); if (pHxp->UrbControlDescriptorRequest.Index == 2) { PUSB_STRING_DESCRIPTOR pDescriptor = (PUSB_STRING_DESCRIPTOR) pHxp->UrbControlDescriptorRequest.TransferBuffer; WCHAR *bString = L"Controller"; USHORT Length; status = STATUS_SUCCESS; Length = (USHORT)((wcslen(bString) + 1) * sizeof(WCHAR)); pDescriptor->bLength = (UCHAR)(sizeof(USB_STRING_DESCRIPTOR) + Length); pDescriptor->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE; if (pHxp->UrbControlDescriptorRequest.TransferBufferLength >= pDescriptor->bLength) { RtlStringCchPrintfW(pDescriptor->bString, Length / sizeof(WCHAR), L"%ws", bString); } } break; case USB_INTERFACE_DESCRIPTOR_TYPE: Bus_KdPrint(("USB_INTERFACE_DESCRIPTOR_TYPE : Buffer %p, Length %d\n", pHxp->UrbControlDescriptorRequest.TransferBuffer, pHxp->UrbControlDescriptorRequest.TransferBufferLength)); break; case USB_ENDPOINT_DESCRIPTOR_TYPE: Bus_KdPrint(("USB_ENDPOINT_DESCRIPTOR_TYPE : Buffer %p, Length %d\n", pHxp->UrbControlDescriptorRequest.TransferBuffer, pHxp->UrbControlDescriptorRequest.TransferBufferLength)); break; default: break; } break; } } break; case IOCTL_INTERNAL_USB_GET_PORT_STATUS: Bus_KdPrint(("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n")); *(unsigned long *) irpStack->Parameters.Others.Argument1 = USBD_PORT_ENABLED | USBD_PORT_CONNECTED; status = STATUS_SUCCESS; break; case IOCTL_INTERNAL_USB_RESET_PORT: Bus_KdPrint(("IOCTL_INTERNAL_USB_RESET_PORT\n")); status = STATUS_SUCCESS; break; default: Bus_KdPrint(("Unknown Ioctrl code\n")); break; } Irp->IoStatus.Information = 0; if(status != STATUS_PENDING) { Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); } return status; }
/** Update the string associated with an existing SMBIOS record. @param This The EFI_SMBIOS_PROTOCOL instance. @param SmbiosHandle SMBIOS Handle of structure that will have its string updated. @param StringNumber The non-zero string number of the string to update @param String Update the StringNumber string with String. @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated. @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports. @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record. **/ EFI_STATUS EFIAPI SmbiosUpdateString ( IN CONST EFI_SMBIOS_PROTOCOL *This, IN EFI_SMBIOS_HANDLE *SmbiosHandle, IN UINTN *StringNumber, IN CHAR8 *String ) { UINTN InputStrLen; UINTN TargetStrLen; UINTN StrIndex; UINTN TargetStrOffset; UINTN NewEntrySize; CHAR8 *StrStart; VOID *Raw; LIST_ENTRY *Link; LIST_ENTRY *Head; EFI_STATUS Status; SMBIOS_INSTANCE *Private; EFI_SMBIOS_ENTRY *SmbiosEntry; EFI_SMBIOS_ENTRY *ResizedSmbiosEntry; EFI_SMBIOS_HANDLE MaxSmbiosHandle; EFI_SMBIOS_TABLE_HEADER *Record; EFI_SMBIOS_RECORD_HEADER *InternalRecord; // // Check args validity // GetMaxSmbiosHandle(This, &MaxSmbiosHandle); if (*SmbiosHandle > MaxSmbiosHandle) { return EFI_INVALID_PARAMETER; } if (String == NULL) { return EFI_ABORTED; } if (*StringNumber == 0) { return EFI_NOT_FOUND; } InputStrLen = AsciiStrLen(String); if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) { if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } } else if (This->MajorVersion < 3) { // // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string. // However, the length of the entire structure table (including all strings) must be reported // in the Structure Table Length field of the SMBIOS Structure Table Entry Point, // which is a WORD field limited to 65,535 bytes. // if (InputStrLen > SMBIOS_TABLE_MAX_LENGTH) { return EFI_UNSUPPORTED; } } else { if (InputStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH) { // // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes. // The input string length should not exceed 0xFFFFFFFF bytes. // return EFI_UNSUPPORTED; } } Private = SMBIOS_INSTANCE_FROM_THIS (This); // // Enter into critical section // Status = EfiAcquireLockOrFail (&Private->DataLock); if (EFI_ERROR (Status)) { return Status; } Head = &Private->DataListHead; for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) { SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link); Record = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1); if (Record->Handle == *SmbiosHandle) { // // Find out the specified SMBIOS record // if (*StringNumber > SmbiosEntry->RecordHeader->NumberOfStrings) { EfiReleaseLock (&Private->DataLock); return EFI_NOT_FOUND; } // // Point to unformed string section // StrStart = (CHAR8 *) Record + Record->Length; for (StrIndex = 1, TargetStrOffset = 0; StrIndex < *StringNumber; StrStart++, TargetStrOffset++) { // // A string ends in 00h // if (*StrStart == 0) { StrIndex++; } // // String section ends in double-null (0000h) // if (*StrStart == 0 && *(StrStart + 1) == 0) { EfiReleaseLock (&Private->DataLock); return EFI_NOT_FOUND; } } if (*StrStart == 0) { StrStart++; TargetStrOffset++; } // // Now we get the string target // TargetStrLen = AsciiStrLen(StrStart); if (InputStrLen == TargetStrLen) { AsciiStrCpyS(StrStart, TargetStrLen + 1, String); // // Some UEFI drivers (such as network) need some information in SMBIOS table. // Here we create SMBIOS table and publish it in // configuration table, so other UEFI drivers can get SMBIOS table from // configuration table without depending on PI SMBIOS protocol. // SmbiosTableConstruction (SmbiosEntry->Smbios32BitTable, SmbiosEntry->Smbios64BitTable); EfiReleaseLock (&Private->DataLock); return EFI_SUCCESS; } SmbiosEntry->Smbios32BitTable = FALSE; SmbiosEntry->Smbios64BitTable = FALSE; if ((This->MajorVersion < 0x3) || ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) { // // 32-bit table is produced, check the valid length. // if ((EntryPointStructure != NULL) && (EntryPointStructure->TableLength + InputStrLen - TargetStrLen > SMBIOS_TABLE_MAX_LENGTH)) { // // The length of the entire structure table (including all strings) must be reported // in the Structure Table Length field of the SMBIOS Structure Table Entry Point, // which is a WORD field limited to 65,535 bytes. // DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 32-bit table length\n")); } else { DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 32-bit table\n")); SmbiosEntry->Smbios32BitTable = TRUE; } } if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) { // // 64-bit table is produced, check the valid length. // if ((Smbios30EntryPointStructure != NULL) && (Smbios30EntryPointStructure->TableMaximumSize + InputStrLen - TargetStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH)) { DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 64-bit table length\n")); } else { DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 64-bit table\n")); SmbiosEntry->Smbios64BitTable = TRUE; } } if ((!SmbiosEntry->Smbios32BitTable) && (!SmbiosEntry->Smbios64BitTable)) { EfiReleaseLock (&Private->DataLock); return EFI_UNSUPPORTED; } // // Original string buffer size is not exactly match input string length. // Re-allocate buffer is needed. // NewEntrySize = SmbiosEntry->RecordSize + InputStrLen - TargetStrLen; ResizedSmbiosEntry = AllocateZeroPool (NewEntrySize); if (ResizedSmbiosEntry == NULL) { EfiReleaseLock (&Private->DataLock); return EFI_OUT_OF_RESOURCES; } InternalRecord = (EFI_SMBIOS_RECORD_HEADER *) (ResizedSmbiosEntry + 1); Raw = (VOID *) (InternalRecord + 1); // // Build internal record Header // InternalRecord->Version = EFI_SMBIOS_RECORD_HEADER_VERSION; InternalRecord->HeaderSize = (UINT16) sizeof (EFI_SMBIOS_RECORD_HEADER); InternalRecord->RecordSize = SmbiosEntry->RecordHeader->RecordSize + InputStrLen - TargetStrLen; InternalRecord->ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle; InternalRecord->NumberOfStrings = SmbiosEntry->RecordHeader->NumberOfStrings; // // Copy SMBIOS structure and optional strings. // CopyMem (Raw, SmbiosEntry->RecordHeader + 1, Record->Length + TargetStrOffset); CopyMem ((VOID*)((UINTN)Raw + Record->Length + TargetStrOffset), String, InputStrLen + 1); CopyMem ((CHAR8*)((UINTN)Raw + Record->Length + TargetStrOffset + InputStrLen + 1), (CHAR8*)Record + Record->Length + TargetStrOffset + TargetStrLen + 1, SmbiosEntry->RecordHeader->RecordSize - sizeof (EFI_SMBIOS_RECORD_HEADER) - Record->Length - TargetStrOffset - TargetStrLen - 1); // // Insert new record // ResizedSmbiosEntry->Signature = EFI_SMBIOS_ENTRY_SIGNATURE; ResizedSmbiosEntry->RecordHeader = InternalRecord; ResizedSmbiosEntry->RecordSize = NewEntrySize; ResizedSmbiosEntry->Smbios32BitTable = SmbiosEntry->Smbios32BitTable; ResizedSmbiosEntry->Smbios64BitTable = SmbiosEntry->Smbios64BitTable; InsertTailList (Link->ForwardLink, &ResizedSmbiosEntry->Link); // // Remove old record // RemoveEntryList(Link); FreePool(SmbiosEntry); // // Some UEFI drivers (such as network) need some information in SMBIOS table. // Here we create SMBIOS table and publish it in // configuration table, so other UEFI drivers can get SMBIOS table from // configuration table without depending on PI SMBIOS protocol. // SmbiosTableConstruction (ResizedSmbiosEntry->Smbios32BitTable, ResizedSmbiosEntry->Smbios64BitTable); EfiReleaseLock (&Private->DataLock); return EFI_SUCCESS; } } EfiReleaseLock (&Private->DataLock); return EFI_INVALID_PARAMETER; }
INT WSAAPI WsNcRefreshFromRegistry(IN PNSCATALOG Catalog, IN HANDLE CatalogEvent) { INT ErrorCode; BOOLEAN LocalEvent = FALSE; LIST_ENTRY LocalList; DWORD UniqueId; HKEY EntriesKey; DWORD CatalogEntries; PNSCATALOG_ENTRY CatalogEntry; BOOL NewChangesMade; PLIST_ENTRY Entry; DWORD RegType = REG_DWORD; DWORD RegSize = sizeof(DWORD); DWORD i; /* Check if we got an event */ if (!CatalogEvent) { /* Create an event ourselves */ CatalogEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (!CatalogEvent) return WSASYSCALLFAILURE; LocalEvent = TRUE; } /* Lock the catalog */ WsNcLock(); /* Initialize our local list for the loop */ InitializeListHead(&LocalList); /* Start looping */ do { /* Setup notifications for the catalog entry */ ErrorCode = WsSetupCatalogProtection(Catalog->CatalogKey, CatalogEvent, &UniqueId); if (ErrorCode != ERROR_SUCCESS) break; /* Check if we've changed till now */ if (UniqueId == Catalog->UniqueId) { /* We haven't, so return */ ErrorCode = ERROR_SUCCESS; break; } /* Now Open the Entries */ ErrorCode = RegOpenKeyEx(Catalog->CatalogKey, "Catalog_Entries", 0, MAXIMUM_ALLOWED, &EntriesKey); if (ErrorCode != ERROR_SUCCESS) { /* Critical failure */ ErrorCode = WSASYSCALLFAILURE; break; } /* Find out how many there are */ ErrorCode = RegQueryValueEx(Catalog->CatalogKey, "Num_Catalog_Entries", 0, &RegType, (LPBYTE)&CatalogEntries, &RegSize); if (ErrorCode != ERROR_SUCCESS) { /* Critical failure */ ErrorCode = WSASYSCALLFAILURE; break; } /* Initialize them all */ for (i = 1; i <= CatalogEntries; i++) { /* Allocate a Catalog Entry Structure */ CatalogEntry = WsNcEntryAllocate(); if (!CatalogEntry) { /* Not enough memory, fail */ ErrorCode = WSA_NOT_ENOUGH_MEMORY; break; } /* Initialize it from the Registry Key */ ErrorCode = WsNcEntryInitializeFromRegistry(CatalogEntry, EntriesKey, i); if (ErrorCode != ERROR_SUCCESS) { /* We failed to get it, dereference the entry and leave */ WsNcEntryDereference(CatalogEntry); break; } /* Insert it to our List */ InsertTailList(&LocalList, &CatalogEntry->CatalogLink); } /* Close the catalog key */ RegCloseKey(EntriesKey); /* Check if we changed during our read and if we have success */ NewChangesMade = WsCheckCatalogState(CatalogEvent); if (!NewChangesMade && ErrorCode == ERROR_SUCCESS) { /* All is good, update the protocol list */ WsNcUpdateNamespaceList(Catalog, &LocalList); /* Update and return */ Catalog->UniqueId = UniqueId; break; } /* We failed and/or catalog data changed, free what we did till now */ while (!IsListEmpty(&LocalList)) { /* Get the LP Catalog Item */ Entry = RemoveHeadList(&LocalList); CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink); /* Dereference it */ WsNcEntryDereference(CatalogEntry); } } while (NewChangesMade); /* Release the lock */ WsNcUnlock(); /* Close the event, if any was created by us */ if (LocalEvent) CloseHandle(CatalogEvent); /* All Done */ return ErrorCode; }
EFI_STATUS BootMenuAddBootOption ( IN LIST_ENTRY *BootOptionsList ) { EFI_STATUS Status; BDS_SUPPORTED_DEVICE* SupportedBootDevice; ARM_BDS_LOADER_ARGUMENTS* BootArguments; CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; CHAR8 AsciiCmdLine[BOOT_DEVICE_OPTION_MAX]; CHAR16 CmdLine[BOOT_DEVICE_OPTION_MAX]; UINT32 Attributes; ARM_BDS_LOADER_TYPE BootType; BDS_LOAD_OPTION_ENTRY *BdsLoadOptionEntry; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePathNodes; EFI_DEVICE_PATH_PROTOCOL *InitrdPathNodes; EFI_DEVICE_PATH_PROTOCOL *InitrdPath; UINTN CmdLineSize; BOOLEAN InitrdSupport; UINTN InitrdSize; UINT8* OptionalData; UINTN OptionalDataSize; Attributes = 0; SupportedBootDevice = NULL; // List the Boot Devices supported Status = SelectBootDevice (&SupportedBootDevice); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } // Create the specific device path node Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } // Append the Device Path to the selected device path DevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)DevicePathNodes); if (DevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } if (SupportedBootDevice->Support->RequestBootType) { Status = BootDeviceGetType (DevicePath, &BootType, &Attributes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } } else { BootType = BDS_LOADER_EFI_APPLICATION; } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { Print(L"Add an initrd: "); Status = GetHIInputBoolean (&InitrdSupport); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } if (InitrdSupport) { // Create the specific device path node Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes); if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd Status = EFI_ABORTED; goto EXIT; } if (InitrdPathNodes != NULL) { // Append the Device Path to the selected device path InitrdPath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes); if (InitrdPath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } } else { InitrdPath = NULL; } } else { InitrdPath = NULL; } Print(L"Arguments to pass to the binary: "); Status = GetHIInputAscii (AsciiCmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } CmdLineSize = AsciiStrSize (AsciiCmdLine); InitrdSize = GetDevicePathSize (InitrdPath); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); BootArguments->LinuxArguments.CmdLineSize = CmdLineSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem ((VOID*)(&BootArguments->LinuxArguments + 1), AsciiCmdLine, CmdLineSize); CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { Print (L"Arguments to pass to the EFI Application: "); Status = GetHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto EXIT; } OptionalData = (UINT8*)CmdLine; OptionalDataSize = StrSize (CmdLine); } Print(L"Description for this new Entry: "); Status = GetHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } // Create new entry BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof(BDS_LOAD_OPTION_ENTRY)); Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption); if (!EFI_ERROR(Status)) { InsertTailList (BootOptionsList, &BdsLoadOptionEntry->Link); } FREE_DEVICE_PATH: FreePool (DevicePath); EXIT: if (Status == EFI_ABORTED) { Print(L"\n"); } FreePool(SupportedBootDevice); return Status; }
VOID WSAAPI WsNcUpdateNamespaceList(IN PNSCATALOG Catalog, IN PLIST_ENTRY List) { LIST_ENTRY TempList; PNSCATALOG_ENTRY CatalogEntry, OldCatalogEntry; PLIST_ENTRY Entry; /* First move from our list to the old one */ InsertHeadList(&Catalog->CatalogList, &TempList); RemoveEntryList(&Catalog->CatalogList); InitializeListHead(&Catalog->CatalogList); /* Loop every item on the list */ while (!IsListEmpty(List)) { /* Get the catalog entry */ Entry = RemoveHeadList(List); CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink); /* Check if this item is already on our list */ Entry = TempList.Flink; while (Entry != &TempList) { /* Get the catalog entry */ OldCatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink); Entry = Entry->Flink; /* Check if they match */ if (memcmp(&CatalogEntry->ProviderId, &OldCatalogEntry->ProviderId, sizeof(GUID))) { /* We have a match, use the old item instead */ WsNcEntryDereference(CatalogEntry); CatalogEntry = OldCatalogEntry; RemoveEntryList(&CatalogEntry->CatalogLink); /* Decrease the number of protocols we have */ Catalog->ItemCount--; break; } } /* Add this item */ InsertTailList(&Catalog->CatalogList, &CatalogEntry->CatalogLink); Catalog->ItemCount++; } /* If there's anything left on the temporary list */ while (!IsListEmpty(&TempList)) { /* Get the entry */ Entry = RemoveHeadList(&TempList); CatalogEntry = CONTAINING_RECORD(Entry, NSCATALOG_ENTRY, CatalogLink); /* Remove it */ Catalog->ItemCount--; WsNcEntryDereference(CatalogEntry); } }
/* * @implemented */ BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { KIRQL OldIrql; PKPRCB Prcb, CurrentPrcb; ULONG Cpu; PKDPC_DATA DpcData; BOOLEAN DpcConfigured = FALSE, DpcInserted = FALSE; ASSERT_DPC(Dpc); /* Check IRQL and Raise it to HIGH_LEVEL */ KeRaiseIrql(HIGH_LEVEL, &OldIrql); CurrentPrcb = KeGetCurrentPrcb(); /* Check if the DPC has more then the maximum number of CPUs */ if (Dpc->Number >= MAXIMUM_PROCESSORS) { /* Then substract the maximum and get that PRCB. */ Cpu = Dpc->Number - MAXIMUM_PROCESSORS; Prcb = KiProcessorBlock[Cpu]; } else { /* Use the current one */ Prcb = CurrentPrcb; Cpu = Prcb->Number; } /* ROS Sanity Check */ ASSERT(Prcb == CurrentPrcb); /* Check if this is a threaded DPC and threaded DPCs are enabled */ if ((Dpc->Type == ThreadedDpcObject) && (Prcb->ThreadDpcEnable)) { /* Then use the threaded data */ DpcData = &Prcb->DpcData[DPC_THREADED]; } else { /* Otherwise, use the regular data */ DpcData = &Prcb->DpcData[DPC_NORMAL]; } /* Acquire the DPC lock */ KiAcquireSpinLock(&DpcData->DpcLock); /* Get the DPC Data */ if (!InterlockedCompareExchangePointer(&Dpc->DpcData, DpcData, NULL)) { /* Now we can play with the DPC safely */ Dpc->SystemArgument1 = SystemArgument1; Dpc->SystemArgument2 = SystemArgument2; DpcData->DpcQueueDepth++; DpcData->DpcCount++; DpcConfigured = TRUE; /* Check if this is a high importance DPC */ if (Dpc->Importance == HighImportance) { /* Pre-empty other DPCs */ InsertHeadList(&DpcData->DpcListHead, &Dpc->DpcListEntry); } else { /* Add it at the end */ InsertTailList(&DpcData->DpcListHead, &Dpc->DpcListEntry); } /* Check if this is the DPC on the threaded list */ if (&Prcb->DpcData[DPC_THREADED] == DpcData) { /* Make sure a threaded DPC isn't already active */ if (!(Prcb->DpcThreadActive) && !(Prcb->DpcThreadRequested)) { /* FIXME: Setup Threaded DPC */ UNIMPLEMENTED_FATAL("Threaded DPC not supported\n"); } } else { /* Make sure a DPC isn't executing already */ if (!(Prcb->DpcRoutineActive) && !(Prcb->DpcInterruptRequested)) { /* Check if this is the same CPU */ if (Prcb != CurrentPrcb) { /* * Check if the DPC is of high importance or above the * maximum depth. If it is, then make sure that the CPU * isn't idle, or that it's sleeping. */ if (((Dpc->Importance == HighImportance) || (DpcData->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) && (!(AFFINITY_MASK(Cpu) & KiIdleSummary) || (Prcb->Sleeping))) { /* Set interrupt requested */ Prcb->DpcInterruptRequested = TRUE; /* Set DPC inserted */ DpcInserted = TRUE; } } else { /* Check if the DPC is of anything but low importance */ if ((Dpc->Importance != LowImportance) || (DpcData->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { /* Set interrupt requested */ Prcb->DpcInterruptRequested = TRUE; /* Set DPC inserted */ DpcInserted = TRUE; } } } } } /* Release the lock */ KiReleaseSpinLock(&DpcData->DpcLock); /* Check if the DPC was inserted */ if (DpcInserted) { /* Check if this was SMP */ if (Prcb != CurrentPrcb) { /* It was, request and IPI */ KiIpiSend(AFFINITY_MASK(Cpu), IPI_DPC); } else { /* It wasn't, request an interrupt from HAL */ HalRequestSoftwareInterrupt(DISPATCH_LEVEL); } } /* Lower IRQL */ KeLowerIrql(OldIrql); return DpcConfigured; }
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().
/** This function attempts to boot for the boot order specified by platform policy. **/ VOID BdsBootDeviceSelect ( VOID ) { EFI_STATUS Status; LIST_ENTRY *Link; BDS_COMMON_OPTION *BootOption; UINTN ExitDataSize; CHAR16 *ExitData; UINT16 Timeout; LIST_ENTRY BootLists; CHAR16 Buffer[20]; BOOLEAN BootNextExist; LIST_ENTRY *LinkBootNext; // // Got the latest boot option // BootNextExist = FALSE; LinkBootNext = NULL; InitializeListHead (&BootLists); // // First check the boot next option // ZeroMem (Buffer, sizeof (Buffer)); if (mBootNext != NULL) { // // Indicate we have the boot next variable, so this time // boot will always have this boot option // BootNextExist = TRUE; // // Clear the this variable so it's only exist in this time boot // gRT->SetVariable ( L"BootNext", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, mBootNext ); // // Add the boot next boot option // UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext); BootOption = BdsLibVariableToOption (&BootLists, Buffer); // // If fail to get boot option from variable, just return and do nothing. // if (BootOption == NULL) { return; } BootOption->BootCurrent = *mBootNext; } // // Parse the boot order to get boot option // BdsLibBuildOptionFromVar (&BootLists, L"BootOrder"); // // When we didn't have chance to build boot option variables in the first // full configuration boot (e.g.: Reset in the first page or in Device Manager), // we have no boot options in the following mini configuration boot. // Give the last chance to enumerate the boot options. // if (IsListEmpty (&BootLists)) { BdsLibEnumerateAllBootOption (&BootLists); } Link = BootLists.ForwardLink; // // Parameter check, make sure the loop will be valid // if (Link == NULL) { return ; } // // Here we make the boot in a loop, every boot success will // return to the front page // for (;;) { // // Check the boot option list first // if (Link == &BootLists) { // // There are two ways to enter here: // 1. There is no active boot option, give user chance to // add new boot option // 2. All the active boot option processed, and there is no // one is success to boot, then we back here to allow user // add new active boot option // Timeout = 0xffff; PlatformBdsEnterFrontPage (Timeout, FALSE); InitializeListHead (&BootLists); BdsLibBuildOptionFromVar (&BootLists, L"BootOrder"); Link = BootLists.ForwardLink; continue; } // // Get the boot option from the link list // BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); // // According to EFI Specification, if a load option is not marked // as LOAD_OPTION_ACTIVE, the boot manager will not automatically // load the option. // if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) { // // skip the header of the link list, because it has no boot option // Link = Link->ForwardLink; continue; } // // Make sure the boot option device path connected, // but ignore the BBS device path // if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) { // // Notes: the internal shell can not been connected with device path // so we do not check the status here // BdsLibConnectDevicePath (BootOption->DevicePath); } // // Restore to original mode before launching boot option. // BdsSetConsoleMode (FALSE); // // All the driver options should have been processed since // now boot will be performed. // Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData); if (Status != EFI_SUCCESS) { // // Call platform action to indicate the boot fail // BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED)); PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize); // // Check the next boot option // Link = Link->ForwardLink; } else { // // Call platform action to indicate the boot success // BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); PlatformBdsBootSuccess (BootOption); // // Boot success, then stop process the boot order, and // present the boot manager menu, front page // Timeout = 0xffff; PlatformBdsEnterFrontPage (Timeout, FALSE); // // Rescan the boot option list, avoid potential risk of the boot // option change in front page // if (BootNextExist) { LinkBootNext = BootLists.ForwardLink; } InitializeListHead (&BootLists); if (LinkBootNext != NULL) { // // Reserve the boot next option // InsertTailList (&BootLists, LinkBootNext); } BdsLibBuildOptionFromVar (&BootLists, L"BootOrder"); Link = BootLists.ForwardLink; } } }
// //发送相关函数的实现、 // NTSTATUS SecLabSendPacket( PADAPT pAdapt, IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp ) { PIO_STACK_LOCATION pIrpSp; ULONG FunctionCode; ULONG DataLength; NTSTATUS NtStatus=STATUS_INVALID_HANDLE; NDIS_STATUS Status; PNDIS_PACKET pNdisPacket; PNDIS_BUFFER pNdisBuffer; // SECLAB_ETH_HEADER UNALIGNED *pEthHeader; PUCHAR pData; ULONG i; #ifdef NDIS51 PVOID CancelId; #endif pIrpSp = IoGetCurrentIrpStackLocation(pIrp); pNdisPacket = NULL; pNdisBuffer = NULL; do { if (pAdapt == NULL) { DbgPrint("Write: FileObject not yet associated with a device\n"); NtStatus = STATUS_INVALID_HANDLE; break; } // // 检查发送数据包的长度 // DataLength=pIrpSp->Parameters.DeviceIoControl.InputBufferLength; if (DataLength > MAX_SEND_PACKETLEN ) { DbgPrint("Write: Open data length larger than max frame size\n"); NtStatus = STATUS_UNSUCCESSFUL; break; } // // 构造一个发送封包 // if(pAdapt->SendPacketPoolHandle==NULL) { DbgPrint("The Packet Pool should not be NULL"); DbgBreakPoint(); break; } do { //其实怎么样分配内存是无关紧要的,忘记资源的释放也不是很严重的 //最多导致内存支出过多。关键是不能让程序引用不存在的内存,这样会 //造成崩溃,比如重复释放内存。崩溃的另一大可能是在Dispatch>=passive //级别上调用非分页内存。 //pData=(PUCHAR)ExAllocatePool(NonPagedPool,DataLength); NdisAllocateMemoryWithTag((PVOID *)(&pData), DataLength,'lceS'); if(pData==NULL) { DbgPrint("Can not allocate pool for send"); break; } //RtlCopyMemory(pData,pIrp->AssociatedIrp.SystemBuffer,DataLength); NdisMoveMemory(pData,pIrp->AssociatedIrp.SystemBuffer,DataLength); // // 将其转化为NDIS_BUFFER. // NdisAllocateBuffer( &Status, &pNdisBuffer, SendBufferPool, pData, DataLength); if (Status != NDIS_STATUS_SUCCESS) { DbgPrint("failed to allocate Ndis Buffer"); break; } NdisAllocatePacket(&Status, &pNdisPacket, pAdapt->SendPacketPoolHandle); if (Status != NDIS_STATUS_SUCCESS) { DbgPrint("failed to alloc NDIS packet"); break; } NDIS_SET_PACKET_STATUS(pNdisPacket, 0); pNdisBuffer->Next = NULL; NdisChainBufferAtFront(pNdisPacket, pNdisBuffer); pNdisPacket->Private.Head->Next=NULL; pNdisPacket->Private.Tail=NULL; break; } while (FALSE); if (pNdisPacket == NULL || pNdisBuffer==NULL) { // // Clean up // if (pNdisBuffer != NULL) { NdisFreeBuffer(pNdisBuffer); } if (pData != NULL) { NdisFreeMemory(pData, 0, 0); } } IoMarkIrpPending(pIrp); NtStatus = STATUS_PENDING; pIrp->IoStatus.Status = STATUS_PENDING; // // 初始化封包中的标志符。当标志符值为0时此包被释放 // SECLAB_SEND_PKT_RSVD(pNdisPacket)->RefCount = 1; #ifdef NDIS51 // // NDIS 5.1 supports cancelling sends. We set up a cancel ID on // each send packet (which maps to a Write IRP), and save the // packet pointer in the IRP. If the IRP gets cancelled, we use // NdisCancelSendPackets() to cancel the packet. // CancelId = SECLAB_GET_NEXT_CANCEL_ID(); NDIS_SET_PACKET_CANCEL_ID(pNdisPacket, CancelId); pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pAdapt; pIrp->Tail.Overlay.DriverContext[1] = (PVOID)pNdisPacket; NdisInterlockedIncrement(&PendedSendCount); NdisAcquireSpinLock(&WriteIrpLock); InsertTailList(&PendedWritesList, &pIrp->Tail.Overlay.ListEntry); IoSetCancelRoutine(pIrp, SecLabCancelWrite); NdisReleaseSpinLock(&WriteIrpLock); #endif // NDIS51 // // 创建一个指针从packet回指向IRP // SECLAB_IRP_FROM_SEND_PKT(pNdisPacket) = pIrp; // //创建三个信号,以便在发送完成例程中指示此包 // SECLAB_SIGNAL1_FROM_SEND_PKT(pNdisPacket)=SIGNAL1; SECLAB_SIGNAL2_FROM_SEND_PKT(pNdisPacket)=SIGNAL2; SECLAB_SIGNAL3_FROM_SEND_PKT(pNdisPacket)=SIGNAL3; // //发包 // NdisSendPackets(pAdapt->BindingHandle, &pNdisPacket, 1); } while (FALSE); if (NtStatus != STATUS_PENDING) { pIrp->IoStatus.Status = NtStatus; IoCompleteRequest(pIrp, IO_NO_INCREMENT); } return (NtStatus); }