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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
/**
  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;
}
Beispiel #5
0
/*****************************************************************************
 * 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;
    }
}
Beispiel #6
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	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));			
Beispiel #7
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #12
0
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;
    }
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #17
0
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 {
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
/**
  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;
}
Beispiel #21
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}
Beispiel #22
0
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;
}
Beispiel #23
0
/**
  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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
0
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);
    }
}
Beispiel #27
0
/*
 * @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);
}