Пример #1
0
/**
  Installs a protocol interface into the boot services environment.

  @param  UserHandle             The handle to install the protocol handler on,
                                 or NULL if a new handle is to be allocated
  @param  Protocol               The protocol to add to the handle
  @param  InterfaceType          Indicates whether Interface is supplied in
                                 native form.
  @param  Interface              The interface for the protocol being added
  @param  Notify                 indicates whether notify the notification list
                                 for this protocol

  @retval EFI_INVALID_PARAMETER  Invalid parameter
  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate
  @retval EFI_SUCCESS            Protocol interface successfully installed

**/
EFI_STATUS
CoreInstallProtocolInterfaceNotify (
  IN OUT EFI_HANDLE     *UserHandle,
  IN EFI_GUID           *Protocol,
  IN EFI_INTERFACE_TYPE InterfaceType,
  IN VOID               *Interface,
  IN BOOLEAN            Notify
  )
{
  PROTOCOL_INTERFACE  *Prot;
  PROTOCOL_ENTRY      *ProtEntry;
  IHANDLE             *Handle;
  EFI_STATUS          Status;
  VOID                *ExistingInterface;

  //
  // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
  // Also added check for invalid UserHandle and Protocol pointers.
  //
  if (UserHandle == NULL || Protocol == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (InterfaceType != EFI_NATIVE_INTERFACE) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Print debug message
  //
  DEBUG((DEBUG_INFO, "InstallProtocolInterface: %g %p\n", Protocol, Interface));

  Status = EFI_OUT_OF_RESOURCES;
  Prot = NULL;
  Handle = NULL;

  if (*UserHandle != NULL) {
    Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);
    if (!EFI_ERROR (Status)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Lock the protocol database
  //
  CoreAcquireProtocolLock ();

  //
  // Lookup the Protocol Entry for the requested protocol
  //
  ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);
  if (ProtEntry == NULL) {
    goto Done;
  }

  //
  // Allocate a new protocol interface structure
  //
  Prot = AllocateZeroPool (sizeof(PROTOCOL_INTERFACE));
  if (Prot == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // If caller didn't supply a handle, allocate a new one
  //
  Handle = (IHANDLE *)*UserHandle;
  if (Handle == NULL) {
    Handle = AllocateZeroPool (sizeof(IHANDLE));
    if (Handle == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    //
    // Initialize new handler structure
    //
    Handle->Signature = EFI_HANDLE_SIGNATURE;
    InitializeListHead (&Handle->Protocols);

    //
    // Initialize the Key to show that the handle has been created/modified
    //
    gHandleDatabaseKey++;
    Handle->Key = gHandleDatabaseKey;

    //
    // Add this handle to the list global list of all handles
    // in the system
    //
    InsertTailList (&gHandleList, &Handle->AllHandles);
  } else {
    Status = CoreValidateHandle (Handle);
    if (EFI_ERROR (Status)) {
      DEBUG((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));
      goto Done;
    }
  }

  //
  // Each interface that is added must be unique
  //
  ASSERT (CoreFindProtocolInterface (Handle, Protocol, Interface) == NULL);

  //
  // Initialize the protocol interface structure
  //
  Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
  Prot->Handle = Handle;
  Prot->Protocol = ProtEntry;
  Prot->Interface = Interface;

  //
  // Initalize OpenProtocol Data base
  //
  InitializeListHead (&Prot->OpenList);
  Prot->OpenListCount = 0;

  //
  // Add this protocol interface to the head of the supported
  // protocol list for this handle
  //
  InsertHeadList (&Handle->Protocols, &Prot->Link);

  //
  // Add this protocol interface to the tail of the
  // protocol entry
  //
  InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);

  //
  // Notify the notification list for this protocol
  //
  if (Notify) {
    CoreNotifyProtocolEntry (ProtEntry);
  }
  Status = EFI_SUCCESS;

Done:
  //
  // Done, unlock the database and return
  //
  CoreReleaseProtocolLock ();
  if (!EFI_ERROR (Status)) {
    //
    // Return the new handle back to the caller
    //
    *UserHandle = Handle;
  } else {
    //
    // There was an error, clean up
    //
    if (Prot != NULL) {
      CoreFreePool (Prot);
    }
    DEBUG((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));
  }

  return Status;
}
Пример #2
0
// ConDrvAddInputEvents
static NTSTATUS
AddInputEvents(PCONSOLE Console,
               PINPUT_RECORD InputRecords, // InputEvent
               ULONG NumEventsToWrite,
               PULONG NumEventsWritten,
               BOOLEAN AppendToEnd)
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG i = 0;
    BOOLEAN SetWaitEvent = FALSE;

    if (NumEventsWritten) *NumEventsWritten = 0;

    /*
     * When adding many single events, in the case of repeated mouse move or
     * key down events, we try to coalesce them so that we do not saturate
     * too quickly the input buffer.
     */
    if (NumEventsToWrite == 1 && !IsListEmpty(&Console->InputBuffer.InputEvents))
    {
        PINPUT_RECORD InputRecord = InputRecords; // Only one element
        PINPUT_RECORD LastInputRecord;
        ConsoleInput* ConInRec; // Input

        /* Get the "next" event of the input buffer */
        if (AppendToEnd)
        {
            /* Get the tail element */
            ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Blink,
                                         ConsoleInput, ListEntry);
        }
        else
        {
            /* Get the head element */
            ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Flink,
                                         ConsoleInput, ListEntry);
        }
        LastInputRecord = &ConInRec->InputEvent;

        if (InputRecord->EventType == MOUSE_EVENT &&
            InputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
        {
            if (LastInputRecord->EventType == MOUSE_EVENT &&
                LastInputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
            {
                /* Update the mouse position */
                LastInputRecord->Event.MouseEvent.dwMousePosition.X =
                    InputRecord->Event.MouseEvent.dwMousePosition.X;
                LastInputRecord->Event.MouseEvent.dwMousePosition.Y =
                    InputRecord->Event.MouseEvent.dwMousePosition.Y;

                i = 1;
                // return STATUS_SUCCESS;
                Status = STATUS_SUCCESS;
            }
        }
        else if (InputRecord->EventType == KEY_EVENT &&
                 InputRecord->Event.KeyEvent.bKeyDown)
        {
            if (LastInputRecord->EventType == KEY_EVENT &&
                LastInputRecord->Event.KeyEvent.bKeyDown &&
                (LastInputRecord->Event.KeyEvent.wVirtualScanCode ==    // Same scancode
                     InputRecord->Event.KeyEvent.wVirtualScanCode) &&
                (LastInputRecord->Event.KeyEvent.uChar.UnicodeChar ==   // Same character
                     InputRecord->Event.KeyEvent.uChar.UnicodeChar) &&
                (LastInputRecord->Event.KeyEvent.dwControlKeyState ==   // Same Ctrl/Alt/Shift state
                     InputRecord->Event.KeyEvent.dwControlKeyState) )
            {
                /* Update the repeat count */
                LastInputRecord->Event.KeyEvent.wRepeatCount +=
                    InputRecord->Event.KeyEvent.wRepeatCount;

                i = 1;
                // return STATUS_SUCCESS;
                Status = STATUS_SUCCESS;
            }
        }
    }

    /* If we coalesced the only one element, we can quit */
    if (i == 1 && Status == STATUS_SUCCESS /* && NumEventsToWrite == 1 */)
        goto Done;

    /*
     * No event coalesced, add them in the usual way.
     */

    if (AppendToEnd)
    {
        /* Go to the beginning of the list */
        // InputRecords = InputRecords;
    }
    else
    {
        /* Go to the end of the list */
        InputRecords = &InputRecords[NumEventsToWrite - 1];
    }

    /* Set the event if the list is going to be non-empty */
    if (IsListEmpty(&Console->InputBuffer.InputEvents))
        SetWaitEvent = TRUE;

    for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
    {
        PINPUT_RECORD InputRecord;
        ConsoleInput* ConInRec;

        if (AppendToEnd)
        {
            /* Select the event and go to the next one */
            InputRecord = InputRecords++;
        }
        else
        {
            /* Select the event and go to the previous one */
            InputRecord = InputRecords--;
        }

        /* Add event to the queue */
        ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
        if (ConInRec == NULL)
        {
            // return STATUS_INSUFFICIENT_RESOURCES;
            Status = STATUS_INSUFFICIENT_RESOURCES;
            continue;
        }

        ConInRec->InputEvent = *InputRecord;

        if (AppendToEnd)
        {
            /* Append the event to the end of the queue */
            InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
        }
        else
        {
            /* Append the event to the beginning of the queue */
            InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
        }

        // return STATUS_SUCCESS;
        Status = STATUS_SUCCESS;
    }

    if (SetWaitEvent) SetEvent(Console->InputBuffer.ActiveEvent);

Done:
    if (NumEventsWritten) *NumEventsWritten = i;

    return Status;
}
Пример #3
0
/*++
* @method: AddListEntry
*
* @description: Add an entry to the list of specified type
*
* @input: eListType eTypeOfList, PVOID pItemToAdd, BOOLEAN bFind
*
* @output: NTSTATUS
*
*--*/
NTSTATUS AddListEntry( eListType eTypeOfList, PVOID pItemToAdd, BOOLEAN bFind )
{
    NTSTATUS retVal = STATUS_UNSUCCESSFUL;
    __try
    {
        // Check if the entry is already present
        if( bFind && ( STATUS_SUCCESS == FindEntry( eTypeOfList, pItemToAdd ) ) )
        {
            retVal = STATUS_DUPLICATE_OBJECTID;
            return retVal;
        }

        // Insert into a list based on type of list
        switch( eTypeOfList )
        {
        case eProcList:
            {
                if( MmIsAddressValid( g_lstArray.pProcListHead ) )
                {
                    PPROCLISTENTRY pNewEntry = NULL;
                    pNewEntry = ExAllocatePoolWithTag( NonPagedPool,
                                                       sizeof( PROCLISTENTRY ),
                                                       ARKITLISTTAG );
                    if( pNewEntry )
                    {
                        RtlZeroMemory( pNewEntry, sizeof( PROCLISTENTRY ) );
                        pNewEntry->dwPID = ((PPROCLISTENTRY)pItemToAdd)->dwPID;
                        RtlStringCchCopyA( pNewEntry->szProcName, ARKITLIB_STR_LEN, ((PPROCLISTENTRY)pItemToAdd)->szProcName );
                        InsertHeadList( g_lstArray.pProcListHead, &( pNewEntry->lEntry ) );
                        retVal = STATUS_SUCCESS;
                    }
                }
            }
            break;

        case eDllList:
            {
                if( MmIsAddressValid( g_lstArray.pDllListHead ) )
                {
                    PDLLLISTENTRY pNewEntry = ExAllocatePoolWithTag( NonPagedPool,
                                                                     sizeof( DLLLISTENTRY ),
                                                                     ARKITLISTTAG );
                    if( pNewEntry )
                    {
                        RtlZeroMemory( pNewEntry, sizeof( DLLLISTENTRY ) );
                        pNewEntry->dwBase = ((PDLLLISTENTRY)pItemToAdd)->dwBase;
                        RtlStringCchCopyA( pNewEntry->szDllName, ARKITLIB_STR_LEN, ((PDLLLISTENTRY)pItemToAdd)->szDllName );
                        InsertHeadList( g_lstArray.pDllListHead, &( pNewEntry->lEntry ) );
                        retVal = STATUS_SUCCESS;
                    }
                }
            }
            break;

        case eDrvList:
            {
                if( MmIsAddressValid( g_lstArray.pDrvListHead ) )
                {
                    PDRIVERLISTENTRY pNewEntry = NULL;
                    pNewEntry = ExAllocatePoolWithTag( NonPagedPool,
                                                       sizeof( DRIVERLISTENTRY ),
                                                       ARKITLISTTAG );
                    if( pNewEntry )
                    {
                        RtlZeroMemory( pNewEntry, sizeof( DRIVERLISTENTRY ) );
                        pNewEntry->dwBase = ((PDRIVERLISTENTRY)pItemToAdd)->dwBase;
                        pNewEntry->dwEnd = ((PDRIVERLISTENTRY)pItemToAdd)->dwEnd;
                        pNewEntry->dwEntryPoint = ((PDRIVERLISTENTRY)pItemToAdd)->dwEntryPoint;
                        RtlStringCchCopyA( pNewEntry->szDrvName, ARKITLIB_STR_LEN, ((PDRIVERLISTENTRY)pItemToAdd)->szDrvName );
                        InsertHeadList( g_lstArray.pDrvListHead, &( pNewEntry->lEntry ) );
                        retVal = STATUS_SUCCESS;
                    }
                }
            }
            break;

        case eSsdtList:
            {
                if( MmIsAddressValid( g_lstArray.pSsdtListHead ) )
                {
                    PSSDTHOOKLISTENTRY pNewEntry = NULL;
                    pNewEntry = ExAllocatePoolWithTag( NonPagedPool,
                                                       sizeof( SSDTHOOKLISTENTRY ),
                                                       ARKITLISTTAG );
                    if( pNewEntry )
                    {
                        RtlZeroMemory( pNewEntry, sizeof( SSDTHOOKLISTENTRY ) );
                        pNewEntry->unIndex = ((PSSDTHOOKLISTENTRY)pItemToAdd)->unIndex;
                        pNewEntry->dwHookAddr = ((PSSDTHOOKLISTENTRY)pItemToAdd)->dwHookAddr;
                        pNewEntry->dwBase = ((PSSDTHOOKLISTENTRY)pItemToAdd)->dwBase;
                        pNewEntry->dwEnd = ((PSSDTHOOKLISTENTRY)pItemToAdd)->dwEnd;
                        RtlStringCchCopyA( pNewEntry->szDrvName, ARKITLIB_STR_LEN, ((PSSDTHOOKLISTENTRY)pItemToAdd)->szDrvName );
                        InsertHeadList( g_lstArray.pSsdtListHead, &( pNewEntry->lEntry ) );
                        retVal = STATUS_SUCCESS;
                    }
                }
            }
            break;

        default:
            {
                retVal = STATUS_UNSUCCESSFUL;
            }
            break;
        }
    }
    __except( EXCEPTION_EXECUTE_HANDLER )
    {
        DbgPrint( "Exception caught in AddListEntry()" );
        retVal = STATUS_UNSUCCESSFUL;
    }
    return retVal;
}
/**
  Open the root directory on a volume.

  @param  This     A pointer to the volume to open the root directory.
  @param  RootFile A pointer to the location to return the opened file handle for the
                   root directory.

  @retval EFI_SUCCESS          The device was opened.
  @retval EFI_UNSUPPORTED      This volume does not support the requested file system type.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
                               longer supported. Any existing file handles for this volume are
                               no longer valid. To access the files on the new medium, the
                               volume must be reopened with OpenVolume().

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemOpenVolume (
  IN     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
     OUT EFI_FILE_PROTOCOL               **RootFile
  )
{
  EFI_STATUS                      Status;
  FV_FILESYSTEM_FILE              *Root;
  CHAR16                          *UiSection;
  EFI_GUID                        NameGuid;
  EFI_FV_FILE_ATTRIBUTES          Attributes;
  UINT32                          Authentication;
  UINTN                           Key;
  EFI_FV_FILETYPE                 FileType;
  UINTN                           Size;
  FV_FILESYSTEM_INSTANCE          *Instance;
  FV_FILESYSTEM_FILE_INFO         *FvFileInfo;
  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FvProtocol;
  CHAR16                          *Name;
  UINTN                           NameLen;
  UINTN                           NumChars;
  UINTN                           DestMax;

  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This);
  Status = EFI_SUCCESS;

  if (Instance->Root == NULL) {
    //
    // Allocate file structure for root file
    //
    Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (Root == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Instance->Root  = Root;
    Root->Instance  = Instance;
    Root->Signature = FVFS_FILE_SIGNATURE;
    CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO));
    if (Root->FvFileInfo == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }
    Root->FvFileInfo->FileInfo.Size      = sizeof (EFI_FILE_INFO);
    Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY;

    //
    // Populate the instance's list of files. We consider anything a file that
    // has a UI_SECTION, which we consider to be its filename.
    //
    FvProtocol = Instance->FvProtocol;
    //
    // Allocate Key
    //
    Key = 0;

    do {
      FileType = EFI_FV_FILETYPE_ALL;

      Status = FvProtocol->GetNextFile (
                             FvProtocol,
                             &Key,
                             &FileType,
                             &NameGuid,
                             &Attributes,
                             &Size
                             );
      if (EFI_ERROR (Status)) {
        ASSERT (Status == EFI_NOT_FOUND);
        break;
      }

      //
      // Get a file's name: If it has a UI section, use that, otherwise use
      // its NameGuid.
      //
      UiSection = NULL;
      Status = FvProtocol->ReadSection (
                             FvProtocol,
                             &NameGuid,
                             EFI_SECTION_USER_INTERFACE,
                             0,
                             (VOID **)&UiSection,
                             &Size,
                             &Authentication
                             );
      if (!EFI_ERROR (Status)) {
        Name = UiSection;
      } else {
        Name = AllocateZeroPool (GUID_STRING_SIZE);
        if (Name == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid);
        ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE);
      }

      //
      // Found a file.
      // Allocate a file structure and populate it.
      //
      NameLen = StrSize (Name);
      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
        NameLen += StrSize (L".efi") - sizeof (CHAR16);
      }

      FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16));
      if (FvFileInfo == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE;
      InitializeListHead (&FvFileInfo->Link);
      CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID));
      FvFileInfo->Type = FileType;

      //
      // Add ".efi" to filenames of drivers and applications.
      //
      DestMax = NameLen / sizeof (CHAR16);
      Status  = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name));
      ASSERT_EFI_ERROR (Status);

      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
        Status  = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi"));
        ASSERT_EFI_ERROR (Status);
      }

      FvFileInfo->FileInfo.Size     = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16);
      Status = FvFsGetFileSize (FvProtocol, FvFileInfo);
      ASSERT_EFI_ERROR (Status);
      FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize;
      FvFileInfo->FileInfo.Attribute    = EFI_FILE_READ_ONLY;

      InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link);

      FreePool (Name);

    } while (TRUE);

    if (Status == EFI_NOT_FOUND) {
      Status = EFI_SUCCESS;
    }
  }

  Instance->Root->DirReadNext = NULL;
  if (!IsListEmpty (&Instance->FileInfoHead)) {
    Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
  }

  *RootFile = &Instance->Root->FileProtocol;
  return Status;
}
Пример #5
0
int TestInterlockedDList(int argc, char* argv[])
{
	ULONG Count;
	PLIST_ITEM pListItem;
	WINPR_PLIST_ENTRY pListHead;
	WINPR_PLIST_ENTRY pListEntry;

	pListHead = (WINPR_PLIST_ENTRY) _aligned_malloc(sizeof(WINPR_LIST_ENTRY), MEMORY_ALLOCATION_ALIGNMENT);

	if (!pListHead)
	{
		printf("Memory allocation failed.\n");
		return -1;
	}

	InitializeListHead(pListHead);

	if (!IsListEmpty(pListHead))
	{
		printf("Expected empty list\n");
		return -1;
	}

	/* InsertHeadList / RemoveHeadList */

	printf("InsertHeadList / RemoveHeadList\n");

	for (Count = 1; Count <= 10; Count += 1)
	{
		pListItem = (PLIST_ITEM) _aligned_malloc(sizeof(LIST_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
		pListItem->Signature = Count;
		InsertHeadList(pListHead, &(pListItem->ItemEntry));
	}

	for (Count = 10; Count >= 1; Count -= 1)
	{
		pListEntry = RemoveHeadList(pListHead);
		pListItem = (PLIST_ITEM) pListEntry;
		_aligned_free(pListEntry);
	}

	/* InsertTailList / RemoveTailList */

	printf("InsertTailList / RemoveTailList\n");

	for (Count = 1; Count <= 10; Count += 1)
	{
		pListItem = (PLIST_ITEM) _aligned_malloc(sizeof(LIST_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
		pListItem->Signature = Count;
		InsertTailList(pListHead, &(pListItem->ItemEntry));
	}

	for (Count = 10; Count >= 1; Count -= 1)
	{
		pListEntry = RemoveTailList(pListHead);
		pListItem = (PLIST_ITEM) pListEntry;
		_aligned_free(pListEntry);
	}

	_aligned_free(pListHead);

	return 0;
}
Пример #6
0
VOID EtpProcessDiskPacket(
    _In_ PETP_DISK_PACKET Packet,
    _In_ ULONG RunId
    )
{
    PET_ETW_DISK_EVENT diskEvent;
    PET_DISK_ITEM diskItem;
    BOOLEAN added = FALSE;

    diskEvent = &Packet->Event;

    // We only process non-zero read/write events.
    if (diskEvent->Type != EtEtwDiskReadType && diskEvent->Type != EtEtwDiskWriteType)
        return;
    if (diskEvent->TransferSize == 0)
        return;

    // Ignore packets with no file name - this is useless to the user.
    if (!Packet->FileName)
        return;

    diskItem = EtReferenceDiskItem(diskEvent->ClientId.UniqueProcess, Packet->FileName);

    if (!diskItem)
    {
        PPH_PROCESS_ITEM processItem;

        // Disk item not found (or the address was re-used), create it.

        diskItem = EtCreateDiskItem();

        diskItem->ProcessId = diskEvent->ClientId.UniqueProcess;
        PhSetReference(&diskItem->FileName, Packet->FileName);
        diskItem->FileNameWin32 = PhGetFileName(diskItem->FileName);

        if (processItem = PhReferenceProcessItem(diskItem->ProcessId))
        {
            PhSetReference(&diskItem->ProcessName, processItem->ProcessName);
            diskItem->ProcessIcon = EtProcIconReferenceSmallProcessIcon(EtGetProcessBlock(processItem));
            diskItem->ProcessRecord = processItem->Record;
            PhReferenceProcessRecord(diskItem->ProcessRecord);

            PhDereferenceObject(processItem);
        }

        // Add the disk item to the age list.
        diskItem->AddTime = RunId;
        diskItem->FreshTime = RunId;
        InsertHeadList(&EtDiskAgeListHead, &diskItem->AgeListEntry);

        // Add the disk item to the hashtable.
        PhAcquireQueuedLockExclusive(&EtDiskHashtableLock);
        PhAddEntryHashtable(EtDiskHashtable, &diskItem);
        PhReleaseQueuedLockExclusive(&EtDiskHashtableLock);

        // Raise the disk item added event.
        PhInvokeCallback(&EtDiskItemAddedEvent, diskItem);
        added = TRUE;
    }

    // The I/O priority number needs to be decoded.

    diskItem->IoPriority = (diskEvent->IrpFlags >> 17) & 7;

    if (diskItem->IoPriority == 0)
        diskItem->IoPriority = IoPriorityNormal;
    else
        diskItem->IoPriority--;

    // Accumulate statistics for this update period.

    if (diskEvent->Type == EtEtwDiskReadType)
        diskItem->ReadDelta += diskEvent->TransferSize;
    else
        diskItem->WriteDelta += diskEvent->TransferSize;

    if (EtpPerformanceFrequency.QuadPart != 0)
    {
        // Convert the response time to milliseconds.
        diskItem->ResponseTimeTotal += (FLOAT)diskEvent->HighResResponseTime * 1000 / EtpPerformanceFrequency.QuadPart;
        diskItem->ResponseTimeCount++;
    }

    if (!added)
    {
        if (diskItem->FreshTime != RunId)
        {
            diskItem->FreshTime = RunId;
            RemoveEntryList(&diskItem->AgeListEntry);
            InsertHeadList(&EtDiskAgeListHead, &diskItem->AgeListEntry);
        }

        PhDereferenceObject(diskItem);
    }
}
Пример #7
0
static
VOID
LoadNotificationDll(
    HKEY hNotifyKey,
    PWSTR pKeyName)
{
    HKEY hDllKey = NULL;
    PNOTIFICATION_ITEM NotificationDll = NULL;
    LONG lError;
    WCHAR szBuffer[80];
    DWORD dwSize;
    DWORD dwType;
    HINSTANCE hInstance;
    NOTIFICATION_TYPE i;

    TRACE("LoadNotificationDll(%p %S)\n", hNotifyKey, pKeyName);

    lError = RegOpenKeyExW(hNotifyKey,
                           pKeyName,
                           0,
                           KEY_READ,
                           &hDllKey);
    if (lError != ERROR_SUCCESS)
        return;

    dwSize = 80 * sizeof(WCHAR);
    lError = RegQueryValueExW(hDllKey,
                              L"DllName",
                              NULL,
                              &dwType,
                              (PBYTE)szBuffer,
                              &dwSize);
    if (lError == ERROR_SUCCESS)
    {
        hInstance = LoadLibraryW(szBuffer);
        if (hInstance == NULL)
            return;

        NotificationDll = RtlAllocateHeap(RtlGetProcessHeap(),
                                          HEAP_ZERO_MEMORY,
                                          sizeof(NOTIFICATION_ITEM));
        if (NotificationDll == NULL)
        {
            FreeLibrary(hInstance);
            return;
        }

        NotificationDll->bEnabled = TRUE;
        NotificationDll->dwMaxWait = 30; /* FIXME: ??? */
        NotificationDll->hInstance = hInstance;

        dwSize = sizeof(BOOL);
        RegQueryValueExW(hDllKey,
                         L"Asynchronous",
                         NULL,
                         &dwType,
                         (PBYTE)&NotificationDll->bAsynchronous,
                         &dwSize);

        dwSize = sizeof(BOOL);
        RegQueryValueExW(hDllKey,
                         L"Enabled",
                         NULL,
                         &dwType,
                         (PBYTE)&NotificationDll->bEnabled,
                         &dwSize);

        dwSize = sizeof(BOOL);
        RegQueryValueExW(hDllKey,
                         L"Impersonate",
                         NULL,
                         &dwType,
                         (PBYTE)&NotificationDll->bImpersonate,
                         &dwSize);

        dwSize = sizeof(BOOL);
        RegQueryValueExW(hDllKey,
                         L"Safe",
                         NULL,
                         &dwType,
                         (PBYTE)&NotificationDll->bSafe,
                         &dwSize);

        dwSize = sizeof(BOOL);
        RegQueryValueExW(hDllKey,
                         L"SmartCardLogonNotify",
                         NULL,
                         &dwType,
                         (PBYTE)&NotificationDll->bSmartCardLogon,
                         &dwSize);

        dwSize = sizeof(DWORD);
        RegQueryValueExW(hDllKey,
                         L"MaxWait",
                         NULL,
                         &dwType,
                         (PBYTE)&NotificationDll->dwMaxWait,
                         &dwSize);

        for (i = LogonHandler; i < LastHandler; i++)
        {
            NotificationDll->Handler[i] = GetNotificationHandler(hDllKey, hInstance, FuncNames[i]);
            TRACE("%s: %p\n", FuncNames[i], NotificationDll->Handler[i]);
        }

        InsertHeadList(&NotificationDllListHead,
                       &NotificationDll->ListEntry);
    }

    RegCloseKey(hDllKey);
}
Пример #8
0
/**
  Internal function to allocate pool of a particular type.
  Caller must have the memory lock held

  @param  PoolType               Type of pool to allocate
  @param  Size                   The amount of pool to allocate

  @return The allocate pool, or NULL

**/
VOID *
CoreAllocatePoolI (
  IN EFI_MEMORY_TYPE  PoolType,
  IN UINTN            Size
  )
{
  POOL        *Pool;
  POOL_FREE   *Free;
  POOL_HEAD   *Head;
  POOL_TAIL   *Tail;
  CHAR8       *NewPage;
  VOID        *Buffer;
  UINTN       Index;
  UINTN       FSize;
  UINTN       Offset;
  UINTN       NoPages;

  ASSERT_LOCKED (&gMemoryLock);

  //
  // Adjust the size by the pool header & tail overhead
  //

  //
  // Adjusting the Size to be of proper alignment so that
  // we don't get an unaligned access fault later when
  // pool_Tail is being initialized
  //
  Size = ALIGN_VARIABLE (Size);

  Size += POOL_OVERHEAD;
  Index = SIZE_TO_LIST(Size);
  Pool = LookupPoolHead (PoolType);
  if (Pool== NULL) {
    return NULL;
  }
  Head = NULL;

  //
  // If allocation is over max size, just allocate pages for the request
  // (slow)
  //
  if (Index >= MAX_POOL_LIST) {
    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
    NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
    Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);
    goto Done;
  }

  //
  // If there's no free pool in the proper list size, go get some more pages
  //
  if (IsListEmpty (&Pool->FreeList[Index])) {

    //
    // Get another page
    //
    NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);
    if (NewPage == NULL) {
      goto Done;
    }

    //
    // Carve up new page into free pool blocks
    //
    Offset = 0;
    while (Offset < DEFAULT_PAGE_ALLOCATION) {
      ASSERT (Index < MAX_POOL_LIST);
      FSize = LIST_TO_SIZE(Index);

      while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
        Free = (POOL_FREE *) &NewPage[Offset];
        Free->Signature = POOL_FREE_SIGNATURE;
        Free->Index     = (UINT32)Index;
        InsertHeadList (&Pool->FreeList[Index], &Free->Link);
        Offset += FSize;
      }

      Index -= 1;
    }

    ASSERT (Offset == DEFAULT_PAGE_ALLOCATION);
    Index = SIZE_TO_LIST(Size);
  }

  //
  // Remove entry from free pool list
  //
  Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);
  RemoveEntryList (&Free->Link);

  Head = (POOL_HEAD *) Free;

Done:
  Buffer = NULL;

  if (Head != NULL) {

    //
    // If we have a pool buffer, fill in the header & tail info
    //
    Head->Signature = POOL_HEAD_SIGNATURE;
    Head->Size      = Size;
    Head->Type      = (EFI_MEMORY_TYPE) PoolType;
    Tail            = HEAD_TO_TAIL (Head);
    Tail->Signature = POOL_TAIL_SIGNATURE;
    Tail->Size      = Size;
    Buffer          = Head->Data;
    DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);

    DEBUG ((
      DEBUG_POOL,
      "AllocatePoolI: Type %x, Addr %p (len %lx) %,ld\n", PoolType,
      Buffer,
      (UINT64)(Size - POOL_OVERHEAD),
      (UINT64) Pool->Used
      ));

    //
    // Account the allocation
    //
    Pool->Used += Size;

  } else {
    DEBUG ((DEBUG_ERROR | DEBUG_POOL, "AllocatePool: failed to allocate %ld bytes\n", (UINT64) Size));
  }

  return Buffer;
}
Пример #9
0
/**
  Internal function to free a pool entry.
  Caller must have the memory lock held

  @param  Buffer                 The allocated pool entry to free

  @retval EFI_INVALID_PARAMETER  Buffer not valid
  @retval EFI_SUCCESS            Buffer successfully freed.

**/
EFI_STATUS
CoreFreePoolI (
  IN VOID       *Buffer
  )
{
  POOL        *Pool;
  POOL_HEAD   *Head;
  POOL_TAIL   *Tail;
  POOL_FREE   *Free;
  UINTN       Index;
  UINTN       NoPages;
  UINTN       Size;
  CHAR8       *NewPage;
  UINTN       FSize;
  UINTN       Offset;
  BOOLEAN     AllFree;

  ASSERT(Buffer != NULL);
  //
  // Get the head & tail of the pool entry
  //
  Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);
  ASSERT(Head != NULL);

  if (Head->Signature != POOL_HEAD_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  Tail = HEAD_TO_TAIL (Head);
  ASSERT(Tail != NULL);

  //
  // Debug
  //
  ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);
  ASSERT (Head->Size == Tail->Size);
  ASSERT_LOCKED (&gMemoryLock);

  if (Tail->Signature != POOL_TAIL_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  if (Head->Size != Tail->Size) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Determine the pool type and account for it
  //
  Size = Head->Size;
  Pool = LookupPoolHead (Head->Type);
  if (Pool == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  Pool->Used -= Size;
  DEBUG ((DEBUG_POOL, "FreePool: %p (len %lx) %,ld\n", Head->Data, (UINT64)(Head->Size - POOL_OVERHEAD), (UINT64) Pool->Used));

  //
  // Determine the pool list
  //
  Index = SIZE_TO_LIST(Size);
  DEBUG_CLEAR_MEMORY (Head, Size);

  //
  // If it's not on the list, it must be pool pages
  //
  if (Index >= MAX_POOL_LIST) {

    //
    // Return the memory pages back to free memory
    //
    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
    NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
    CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);

  } else {

    //
    // Put the pool entry onto the free pool list
    //
    Free = (POOL_FREE *) Head;
    ASSERT(Free != NULL);
    Free->Signature = POOL_FREE_SIGNATURE;
    Free->Index     = (UINT32)Index;
    InsertHeadList (&Pool->FreeList[Index], &Free->Link);

    //
    // See if all the pool entries in the same page as Free are freed pool
    // entries
    //
    NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));
    Free = (POOL_FREE *) &NewPage[0];
    ASSERT(Free != NULL);

    if (Free->Signature == POOL_FREE_SIGNATURE) {

      Index = Free->Index;

      AllFree = TRUE;
      Offset = 0;

      while ((Offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {
        FSize = LIST_TO_SIZE(Index);
        while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
          Free = (POOL_FREE *) &NewPage[Offset];
          ASSERT(Free != NULL);
          if (Free->Signature != POOL_FREE_SIGNATURE) {
            AllFree = FALSE;
          }
          Offset += FSize;
        }
        Index -= 1;
      }

      if (AllFree) {

        //
        // All of the pool entries in the same page as Free are free pool
        // entries
        // Remove all of these pool entries from the free loop lists.
        //
        Free = (POOL_FREE *) &NewPage[0];
        ASSERT(Free != NULL);
        Index = Free->Index;
        Offset = 0;

        while (Offset < DEFAULT_PAGE_ALLOCATION) {
          FSize = LIST_TO_SIZE(Index);
          while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
            Free = (POOL_FREE *) &NewPage[Offset];
            ASSERT(Free != NULL);
            RemoveEntryList (&Free->Link);
            Offset += FSize;
          }
          Index -= 1;
        }

        //
        // Free the page
        //
        CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));
      }
    }
  }

  //
  // If this is an OS specific memory type, then check to see if the last
  // portion of that memory type has been freed.  If it has, then free the
  // list entry for that memory type
  //
  if ((INT32)Pool->MemoryType < 0 && Pool->Used == 0) {
    RemoveEntryList (&Pool->Link);
    CoreFreePoolI (Pool);
  }

  return EFI_SUCCESS;
}
Пример #10
0
NTSTATUS
t1394Cmdr_IoControl(
		IN PDEVICE_OBJECT 	DeviceObject,
		IN PIRP 						Irp
		)
{
	NTSTATUS								ntStatus = STATUS_SUCCESS;
	PIO_STACK_LOCATION			IrpSp;
	PDEVICE_EXTENSION 			deviceExtension;
	PVOID 									ioBuffer;
	ULONG 									inputBufferLength;
	ULONG 									outputBufferLength;
	ULONG 									ioControlCode;
		
	ENTER("t1394Cmdr_IoControl");

	// Get a pointer to the current location in the Irp. This is where
	// the function codes and parameters are located.
	IrpSp = IoGetCurrentIrpStackLocation(Irp);

	// Get a pointer to the device extension
	deviceExtension = DeviceObject->DeviceExtension;

	// Get the pointer to the input/output buffer and it's length
	ioBuffer					 = Irp->AssociatedIrp.SystemBuffer;
	inputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
	outputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;

	// make sure our device isn't in shutdown mode...
	if (deviceExtension->bShutdown) {

		Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		ntStatus = STATUS_NO_SUCH_DEVICE;
		return(ntStatus);
	}

	TRACE(TL_TRACE, ("Irp = 0x%x\n", Irp));
	switch (IrpSp->MajorFunction) 
  {
#define IOCTL_CASE_PRINT(code) case code: TRACE(TL_TRACE,(#code));

		case IRP_MJ_DEVICE_CONTROL:
	TRACE(TL_TRACE, ("t1394Cmdr_IoControl: IRP_MJ_DEVICE_CONTROL\n"));

	ioControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;

	switch (ioControlCode) {
		/*
			case IOCTL_ALLOCATE_ADDRESS_RANGE:
			{
			PALLOCATE_ADDRESS_RANGE 		AllocateAddressRange;

			TRACE(TL_TRACE, ("IOCTL_ALLOCATE_ADDRESS_RANGE\n"));

			if ((inputBufferLength < sizeof(ALLOCATE_ADDRESS_RANGE)) ||
			(outputBufferLength < sizeof(ALLOCATE_ADDRESS_RANGE))) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			AllocateAddressRange = (PALLOCATE_ADDRESS_RANGE)ioBuffer;

			ntStatus = t1394_AllocateAddressRange( DeviceObject,
			Irp,
			AllocateAddressRange->fulAllocateFlags,
			AllocateAddressRange->fulFlags,
			AllocateAddressRange->nLength,
			AllocateAddressRange->MaxSegmentSize,
			AllocateAddressRange->fulAccessType,
			AllocateAddressRange->fulNotificationOptions,
			&AllocateAddressRange->Required1394Offset,
			&AllocateAddressRange->hAddressRange,
			(PULONG)&AllocateAddressRange->Data
			);

			if (NT_SUCCESS(ntStatus))
			Irp->IoStatus.Information = outputBufferLength;
			}
			}
			break; // IOCTL_ALLOCATE_ADDRESS_RANGE

			case IOCTL_FREE_ADDRESS_RANGE:
			TRACE(TL_TRACE, ("IOCTL_FREE_ADDRESS_RANGE\n"));

			if (inputBufferLength < sizeof(HANDLE)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			ntStatus = t1394_FreeAddressRange( DeviceObject,
			Irp,
			*(PHANDLE)ioBuffer
			);
			}
			break; // IOCTL_FREE_ADDRESS_RANGE

			case IOCTL_ASYNC_READ:
			{
			PASYNC_READ 		AsyncRead;

			TRACE(TL_TRACE, ("IOCTL_ASYNC_READ\n"));

			if (inputBufferLength < sizeof(ASYNC_READ)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			AsyncRead = (PASYNC_READ)ioBuffer;

			if ((outputBufferLength < sizeof(ASYNC_READ)) || 
			(outputBufferLength-sizeof(ASYNC_READ) < AsyncRead->nNumberOfBytesToRead)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			ntStatus = t1394_AsyncRead( DeviceObject,
			Irp,
			AsyncRead->bRawMode,
			AsyncRead->bGetGeneration,
			AsyncRead->DestinationAddress,
			AsyncRead->nNumberOfBytesToRead,
			AsyncRead->nBlockSize,
			AsyncRead->fulFlags,
			AsyncRead->ulGeneration,
			(PULONG)&AsyncRead->Data
			);

			if (NT_SUCCESS(ntStatus))
			Irp->IoStatus.Information = outputBufferLength;
			}
			}
			}
			break; // IOCTL_ASYNC_READ

			case IOCTL_ASYNC_WRITE:
			{
			PASYNC_WRITE		AsyncWrite;

			TRACE(TL_TRACE, ("IOCTL_ASYNC_WRITE\n"));

			if (inputBufferLength < sizeof(ASYNC_WRITE)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			AsyncWrite = (PASYNC_WRITE)ioBuffer;

			if (inputBufferLength-sizeof(ASYNC_WRITE) < AsyncWrite->nNumberOfBytesToWrite) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			ntStatus = t1394_AsyncWrite( DeviceObject,
			Irp,
			AsyncWrite->bRawMode,
			AsyncWrite->bGetGeneration,
			AsyncWrite->DestinationAddress,
			AsyncWrite->nNumberOfBytesToWrite,
			AsyncWrite->nBlockSize,
			AsyncWrite->fulFlags,
			AsyncWrite->ulGeneration,
			(PULONG)&AsyncWrite->Data
			);
			}
			}
			}
			break; // IOCTL_ASYNC_WRITE

			case IOCTL_ASYNC_LOCK:
			{
			PASYNC_LOCK 		AsyncLock;

			TRACE(TL_TRACE, ("IOCTL_ASYNC_LOCK\n"));

			if ((inputBufferLength < sizeof(ASYNC_LOCK)) ||
			(outputBufferLength < sizeof(ASYNC_LOCK))) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			AsyncLock = (PASYNC_LOCK)ioBuffer;

			ntStatus = t1394_AsyncLock( DeviceObject,
			Irp,
			AsyncLock->bRawMode,
			AsyncLock->bGetGeneration,
			AsyncLock->DestinationAddress,
			AsyncLock->nNumberOfArgBytes,
			AsyncLock->nNumberOfDataBytes,
			AsyncLock->fulTransactionType,
			AsyncLock->fulFlags,
			AsyncLock->Arguments,
			AsyncLock->DataValues,
			AsyncLock->ulGeneration,
			(PVOID)&AsyncLock->Buffer
			);

			if (NT_SUCCESS(ntStatus))
			Irp->IoStatus.Information = outputBufferLength;
			}
			}
			break; // IOCTL_ASYNC_LOCK

			case IOCTL_ASYNC_STREAM:
			{
			PASYNC_STREAM 	AsyncStream;

			TRACE(TL_TRACE, ("IOCTL_ASYNC_STREAM\n"));

			if (inputBufferLength < sizeof(ASYNC_STREAM)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			AsyncStream = (PASYNC_STREAM)ioBuffer;

			if (outputBufferLength < sizeof(ASYNC_STREAM)+AsyncStream->nNumberOfBytesToStream) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			ntStatus = t1394_AsyncStream( DeviceObject,
			Irp,
			AsyncStream->nNumberOfBytesToStream,
			AsyncStream->fulFlags,
			AsyncStream->ulTag,
			AsyncStream->nChannel,
			AsyncStream->ulSynch,
			(UCHAR)AsyncStream->nSpeed,
			(PULONG)&AsyncStream->Data
			);

			if (NT_SUCCESS(ntStatus))
			Irp->IoStatus.Information = outputBufferLength;
			}
			}
			}
			break; // IOCTL_ASYNC_STREAM
		*/
/* deprecated RESOURCE IOCTLS
	case IOCTL_ISOCH_ALLOCATE_BANDWIDTH:
		{
			PISOCH_ALLOCATE_BANDWIDTH 	IsochAllocateBandwidth;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_ALLOCATE_BANDWIDTH\n"));

			if ((inputBufferLength < sizeof(ISOCH_ALLOCATE_BANDWIDTH)) ||
		(outputBufferLength < sizeof(ISOCH_ALLOCATE_BANDWIDTH))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochAllocateBandwidth = (PISOCH_ALLOCATE_BANDWIDTH)ioBuffer;

	ntStatus = t1394_IsochAllocateBandwidth( DeviceObject,
						 Irp,
						 IsochAllocateBandwidth->nMaxBytesPerFrameRequested,
						 IsochAllocateBandwidth->fulSpeed,
						 &IsochAllocateBandwidth->hBandwidth,
						 &IsochAllocateBandwidth->BytesPerFrameAvailable,
						 &IsochAllocateBandwidth->SpeedSelected
						 );

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_ISOCH_ALLOCATE_BANDWIDTH

	case IOCTL_ISOCH_ALLOCATE_CHANNEL:
		{
			PISOCH_ALLOCATE_CHANNEL 		IsochAllocateChannel;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_ALLOCATE_CHANNEL\n"));

			if ((inputBufferLength < sizeof(ISOCH_ALLOCATE_CHANNEL)) ||
		(outputBufferLength < sizeof(ISOCH_ALLOCATE_CHANNEL))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochAllocateChannel = (PISOCH_ALLOCATE_CHANNEL)ioBuffer;

	ntStatus = t1394_IsochAllocateChannel( DeviceObject,
								 Irp,
								 IsochAllocateChannel->nRequestedChannel,
								 &IsochAllocateChannel->Channel,
								 &IsochAllocateChannel->ChannelsAvailable
								 );

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_ISOCH_ALLOCATE_CHANNEL

	case IOCTL_ISOCH_ALLOCATE_RESOURCES:
		{
			PISOCH_ALLOCATE_RESOURCES 	IsochAllocateResources;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_ALLOCATE_RESOURCES\n"));

			if ((inputBufferLength < sizeof(ISOCH_ALLOCATE_RESOURCES)) ||
		(outputBufferLength < sizeof(ISOCH_ALLOCATE_RESOURCES))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochAllocateResources = (PISOCH_ALLOCATE_RESOURCES)ioBuffer;

	ntStatus = t1394_IsochAllocateResources( DeviceObject,
						 Irp,
						 IsochAllocateResources->fulSpeed,
						 IsochAllocateResources->fulFlags,
						 IsochAllocateResources->nChannel,
						 IsochAllocateResources->nMaxBytesPerFrame,
						 IsochAllocateResources->nNumberOfBuffers,
						 IsochAllocateResources->nMaxBufferSize,
						 IsochAllocateResources->nQuadletsToStrip,
						 &IsochAllocateResources->hResource
						 );

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_ISOCH_ALLOCATE_RESOURCES

  case IOCTL_ISOCH_ATTACH_BUFFERS:
	case IOCTL_ISOCH_DETACH_BUFFERS:
    TRACE(TL_ERROR,("Old-Style [Attach,Detach]Buffers is Deprecated, use IOCTL_ATTACH_BUFFER\n"));
    ntStatus = STATUS_NOT_IMPLEMENTED;
    break;
	case IOCTL_ISOCH_FREE_BANDWIDTH:
		{
			TRACE(TL_TRACE, ("IOCTL_ISOCH_FREE_BANDWIDTH\n"));

			if (inputBufferLength < sizeof(HANDLE)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_IsochFreeBandwidth( DeviceObject,
							 Irp,
							 *(PHANDLE)ioBuffer
							 );
			}
		}
		break; // IOCTL_ISOCH_FREE_BANDWIDTH
	
	case IOCTL_ISOCH_FREE_CHANNEL:
		{
			TRACE(TL_TRACE, ("IOCTL_ISOCH_FREE_CHANNEL\n"));

			if (inputBufferLength < sizeof(ULONG)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_IsochFreeChannel( DeviceObject,
						 Irp,
						 *(PULONG)ioBuffer
						 );
			}
		}
		break; // IOCTL_ISOCH_FREE_CHANNEL
	
	case IOCTL_ISOCH_FREE_RESOURCES:
		{
			TRACE(TL_TRACE, ("IOCTL_ISOCH_FREE_RESOURCES\n"));

			if (inputBufferLength < sizeof(HANDLE)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_IsochFreeResources( DeviceObject,
							 Irp,
							 *(PHANDLE)ioBuffer
							 );
			}
		}
		break; // IOCTL_ISOCH_FREE_RESOURCES
  */
	case IOCTL_ISOCH_LISTEN:
	{
    TRACE(TL_TRACE, ("IOCTL_ISOCH_LISTEN\n"));
    ntStatus = t1394_IsochListen( DeviceObject,Irp);
	}
	break; // IOCTL_ISOCH_LISTEN

	case IOCTL_ISOCH_QUERY_CURRENT_CYCLE_TIME:
		{
			TRACE(TL_TRACE, ("IOCTL_ISOCH_QUERY_CURRENT_CYCLE_TIME\n"));

			if (outputBufferLength < sizeof(CYCLE_TIME)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_IsochQueryCurrentCycleTime( DeviceObject,
								 Irp,
								 (PCYCLE_TIME)ioBuffer
								 );

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_ISOCH_QUERY_CURRENT_CYCLE_TIME

	case IOCTL_ISOCH_QUERY_RESOURCES:
		{
			PISOCH_QUERY_RESOURCES			IsochQueryResources;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_QUERY_RESOURCES\n"));

			if ((inputBufferLength < sizeof(ISOCH_QUERY_RESOURCES)) ||
		(outputBufferLength < sizeof(ISOCH_QUERY_RESOURCES))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochQueryResources = (PISOCH_QUERY_RESOURCES)ioBuffer;

	ntStatus = t1394_IsochQueryResources( DeviceObject,
								Irp,
								IsochQueryResources->fulSpeed,
								&IsochQueryResources->BytesPerFrameAvailable,
								&IsochQueryResources->ChannelsAvailable
								);

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_ISOCH_QUERY_RESOURCES
/*
	case IOCTL_ISOCH_SET_CHANNEL_BANDWIDTH:
		{
			PISOCH_SET_CHANNEL_BANDWIDTH		IsochSetChannelBandwidth;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_SET_CHANNEL_BANDWIDTH\n"));

			if (inputBufferLength < sizeof(ISOCH_SET_CHANNEL_BANDWIDTH)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochSetChannelBandwidth = (PISOCH_SET_CHANNEL_BANDWIDTH)ioBuffer;

	ntStatus = t1394_IsochSetChannelBandwidth( DeviceObject,
							 Irp,
							 IsochSetChannelBandwidth->hBandwidth,
							 IsochSetChannelBandwidth->nMaxBytesPerFrame
							 );
			}
		}
		break; // IOCTL_ISOCH_SET_CHANNEL_BANDWIDTH

	case IOCTL_ISOCH_MODIFY_STREAM_PROPERTIES:
		{
			PISOCH_MODIFY_STREAM_PROPERTIES 		IsochModifyStreamProperties;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_MODIFY_STREAM_PROPERTIES\n"));

			if (inputBufferLength < sizeof (ISOCH_MODIFY_STREAM_PROPERTIES)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochModifyStreamProperties = (PISOCH_MODIFY_STREAM_PROPERTIES)ioBuffer;

	ntStatus = t1394_IsochModifyStreamProperties( DeviceObject,
									Irp, 
									IsochModifyStreamProperties->hResource,
									IsochModifyStreamProperties->ChannelMask,
									IsochModifyStreamProperties->fulSpeed
									);
			}
		}
		break; // IOCTL_ISOCH_MODIFY_STREAM_PROPERTIES
*/
	case IOCTL_ISOCH_STOP:
	  ntStatus = t1394_IsochStop(DeviceObject,Irp);
		break; // IOCTL_ISOCH_STOP
/*
	case IOCTL_ISOCH_TALK:
		{
			PISOCH_TALK 		IsochTalk;

			TRACE(TL_TRACE, ("IOCTL_ISOCH_TALK\n"));

			if (inputBufferLength < sizeof(ISOCH_TALK)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	IsochTalk = (PISOCH_TALK)ioBuffer;

	ntStatus = t1394_IsochTalk( DeviceObject,
						Irp,
						IsochTalk->hResource,
						IsochTalk->fulFlags,
						IsochTalk->StartTime
						);
			}
		}
		break; // IOCTL_ISOCH_TALK
*/
	case IOCTL_GET_LOCAL_HOST_INFORMATION:
		{
			PGET_LOCAL_HOST_INFORMATION 		GetLocalHostInformation;

			TRACE(TL_TRACE, ("IOCTL_GET_LOCAL_HOST_INFORMATION\n"));

			if ((inputBufferLength < sizeof(GET_LOCAL_HOST_INFORMATION)) ||
		(outputBufferLength < sizeof(GET_LOCAL_HOST_INFORMATION))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	GetLocalHostInformation = (PGET_LOCAL_HOST_INFORMATION)ioBuffer;

	ntStatus = t1394_GetLocalHostInformation( DeviceObject,
							Irp,
							GetLocalHostInformation->nLevel,
							&GetLocalHostInformation->Status,
							(PVOID)GetLocalHostInformation->Information
							);

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_GET_LOCAL_HOST_INFORMATION
/*
	case IOCTL_GET_1394_ADDRESS_FROM_DEVICE_OBJECT:
		{
			PGET_1394_ADDRESS 	Get1394Address;

			TRACE(TL_TRACE, ("IOCTL_GET_1394_ADDRESS_FROM_DEVICE_OBJECT\n"));

			if ((inputBufferLength < sizeof(GET_1394_ADDRESS)) ||
		(outputBufferLength < sizeof(GET_1394_ADDRESS))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	Get1394Address = (PGET_1394_ADDRESS)ioBuffer;

	ntStatus = t1394_Get1394AddressFromDeviceObject( DeviceObject,
							 Irp,
							 Get1394Address->fulFlags,
							 &Get1394Address->NodeAddress
							 );

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_GET_1394_ADDRESS_FROM_DEVICE_OBJECT

	case IOCTL_CONTROL:
		TRACE(TL_TRACE, ("IOCTL_CONTROL\n"));

		ntStatus = t1394_Control( DeviceObject,
						Irp
						);

		break; // IOCTL_CONTROL
*/
	case IOCTL_GET_MAX_SPEED_BETWEEN_DEVICES:
		{
			PGET_MAX_SPEED_BETWEEN_DEVICES	MaxSpeedBetweenDevices;

			TRACE(TL_TRACE, ("IOCTL_GET_MAX_SPEED_BETWEEN_DEVICES\n"));

			if ((inputBufferLength < sizeof(GET_MAX_SPEED_BETWEEN_DEVICES)) ||
		(outputBufferLength < sizeof(GET_MAX_SPEED_BETWEEN_DEVICES))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	MaxSpeedBetweenDevices = (PGET_MAX_SPEED_BETWEEN_DEVICES)ioBuffer;

	ntStatus = t1394_GetMaxSpeedBetweenDevices( DeviceObject,
								Irp,
								MaxSpeedBetweenDevices->fulFlags,
								MaxSpeedBetweenDevices->ulNumberOfDestinations,
								(PDEVICE_OBJECT *)&MaxSpeedBetweenDevices->hDestinationDeviceObjects[0],
								&MaxSpeedBetweenDevices->fulSpeed
								);

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		} 									 
		break; // IOCTL_GET_MAX_SPEED_BETWEEN_DEVICES
/*
	case IOCTL_SET_DEVICE_XMIT_PROPERTIES:
		{
			PDEVICE_XMIT_PROPERTIES 		DeviceXmitProperties;

			TRACE(TL_TRACE, ("IOCTL_SET_DEVICE_XMIT_PROPERTIES\n"));

			if (inputBufferLength < sizeof(DEVICE_XMIT_PROPERTIES)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	DeviceXmitProperties = (PDEVICE_XMIT_PROPERTIES)ioBuffer;

	ntStatus = t1394_SetDeviceXmitProperties( DeviceObject,
							Irp,
							DeviceXmitProperties->fulSpeed,
							DeviceXmitProperties->fulPriority
							);
			}
		}
		break; // IOCTL_SET_DEVICE_XMIT_PROPERTIES
*/
	case IOCTL_GET_CONFIGURATION_INFORMATION:
		TRACE(TL_TRACE, ("IOCTL_GET_CONFIGURATION_INFORMATION\n"));

		ntStatus = t1394_GetConfigurationInformation( DeviceObject,
							Irp
							);

		break; // IOCTL_GET_CONFIGURATION_INFORMATION

	case IOCTL_BUS_RESET:
		{
			TRACE(TL_TRACE, ("IOCTL_BUS_RESET\n"));

			if (inputBufferLength < sizeof(ULONG)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_BusReset( DeviceObject,
					 Irp,
					 *((PULONG)ioBuffer)
					 );
			}
		}
		break; // IOCTL_BUS_RESET

	case IOCTL_GET_GENERATION_COUNT:
		{
			TRACE(TL_TRACE, ("IOCTL_GET_GENERATION_COUNT\n"));

			if (outputBufferLength < sizeof(ULONG)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_GetGenerationCount( DeviceObject,
							 Irp,
							 (PULONG)ioBuffer
							 );

	if (NT_SUCCESS(ntStatus))
		Irp->IoStatus.Information = outputBufferLength;
			}
		}
		break; // IOCTL_GET_GENERATION_COUNT

	case IOCTL_SEND_PHY_CONFIGURATION_PACKET:
		{
			TRACE(TL_TRACE, ("IOCTL_SEND_PHY_CONFIGURATION_PACKET\n"));

			if (inputBufferLength < sizeof(PHY_CONFIGURATION_PACKET)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_SendPhyConfigurationPacket( DeviceObject,
								 Irp,
								 *(PPHY_CONFIGURATION_PACKET)ioBuffer
								 );
			}
		}
		break; // IOCTL_SEND_PHY_CONFIGURATION_PACKET

	case IOCTL_BUS_RESET_NOTIFICATION:
		{
			TRACE(TL_TRACE, ("IOCTL_BUS_RESET_NOTIFICATION\n"));

			if (inputBufferLength < sizeof(ULONG)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	ntStatus = t1394_BusResetNotification( DeviceObject,
								 Irp,
								 *((PULONG)ioBuffer)
								 );
			}
		}
		break; // IOCTL_BUS_RESET_NOTIFICATION
/*
	case IOCTL_SET_LOCAL_HOST_INFORMATION:
		{
			PSET_LOCAL_HOST_INFORMATION 		SetLocalHostInformation;

			TRACE(TL_TRACE, ("IOCTL_SET_LOCAL_HOST_INFORMATION\n"));

			if (inputBufferLength < sizeof(SET_LOCAL_HOST_INFORMATION)) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	SetLocalHostInformation = (PSET_LOCAL_HOST_INFORMATION)ioBuffer;

	if (inputBufferLength < (sizeof(SET_LOCAL_HOST_INFORMATION) +
				 SetLocalHostInformation->ulBufferSize)) {

		ntStatus = STATUS_BUFFER_TOO_SMALL;
	}
	else {

		ntStatus = t1394_SetLocalHostProperties( DeviceObject,
							 Irp,
							 SetLocalHostInformation->nLevel,
							 (PVOID)&SetLocalHostInformation->Information
							 );

		if (NT_SUCCESS(ntStatus))
			Irp->IoStatus.Information = outputBufferLength;
	}
			}
		}
		break; // IOCTL_SET_LOCAL_HOST_INFORMATION
		*/
		/*
			case IOCTL_SET_ADDRESS_DATA:
			{
			PSET_ADDRESS_DATA 	SetAddressData;

			TRACE(TL_TRACE, ("IOCTL_SET_ADDRESS_DATA\n"));

			if (inputBufferLength < sizeof(SET_ADDRESS_DATA)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			SetAddressData = (PSET_ADDRESS_DATA)ioBuffer;

			if (inputBufferLength < (sizeof(SET_ADDRESS_DATA)+SetAddressData->nLength)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			ntStatus = t1394_SetAddressData( DeviceObject,
			Irp,
			SetAddressData->hAddressRange,
			SetAddressData->nLength,
			SetAddressData->ulOffset,
			(PVOID)&SetAddressData->Data
			);
			}
			}
			}
			break; // IOCTL_SET_ADDRESS_DATA

			case IOCTL_GET_ADDRESS_DATA:
			{
			PGET_ADDRESS_DATA 	GetAddressData;

			TRACE(TL_TRACE, ("IOCTL_GET_ADDRESS_DATA\n"));

			if (inputBufferLength < sizeof(GET_ADDRESS_DATA)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			GetAddressData = (PGET_ADDRESS_DATA)ioBuffer;

			if (inputBufferLength < (sizeof(GET_ADDRESS_DATA)+GetAddressData->nLength)) {

			ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

			ntStatus = t1394_GetAddressData( DeviceObject,
			Irp,
			GetAddressData->hAddressRange,
			GetAddressData->nLength,
			GetAddressData->ulOffset,
			(PVOID)&GetAddressData->Data
			);
																
			if (NT_SUCCESS(ntStatus))
			Irp->IoStatus.Information = outputBufferLength;
			}
			}
			}
			break; // IOCTL_GET_ADDRESS_DATA
		*/
	case IOCTL_BUS_RESET_NOTIFY: {

		PBUS_RESET_IRP	BusResetIrp;
		KIRQL 					Irql;
										
		TRACE(TL_TRACE, ("IOCTL_BUS_RESET_NOTIFY\n"));

		BusResetIrp = ExAllocatePool(NonPagedPool, sizeof(BUS_RESET_IRP));

		if (BusResetIrp) {

			// mark it pending
			IoMarkIrpPending(Irp);
			ntStatus = Irp->IoStatus.Status = STATUS_PENDING;
			BusResetIrp->Irp = Irp;

			TRACE(TL_TRACE, ("Adding BusResetIrp->Irp = 0x%x\n", BusResetIrp->Irp));

			// add the irp to the list...
			KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql);

			InsertHeadList(&deviceExtension->BusResetIrps, &BusResetIrp->BusResetIrpList);

			// set the cancel routine for the irp
			IoSetCancelRoutine(Irp, t1394Cmdr_CancelIrp);

			if (Irp->Cancel && IoSetCancelRoutine(Irp, t1394Cmdr_CancelIrp)) {

	RemoveEntryList(&BusResetIrp->BusResetIrpList);
	ntStatus = STATUS_CANCELLED;
			}

			KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql);

			// goto _exit on success so we don't complete the irp
			if (ntStatus == STATUS_PENDING)
	goto _exit;
		}
		else
			ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}
		break; // IOCTL_BUS_RESET_NOTIFY

	case IOCTL_GET_CMDR_VERSION:
		{
			PVERSION_DATA 	Version;

			TRACE(TL_TRACE, ("IOCTL_GET_DIAG_VERSION\n"));

			if ((inputBufferLength < sizeof(VERSION_DATA)) &&
		(outputBufferLength < sizeof(VERSION_DATA))) {

	ntStatus = STATUS_BUFFER_TOO_SMALL;
			}
			else {

	Version = (PVERSION_DATA)ioBuffer;
	Version->usMajor;
	Version->usMinor;
	Version->usRevision;
	Version->usBuild;

	Irp->IoStatus.Information = outputBufferLength; 													
			}
		}
		break; // IOCTL_GET_CMDR_VERSION

		//////////////////////////////
		// these added for 1394cmdr //
		//////////////////////////////
	case IOCTL_SET_CMDR_TRACELEVEL:
		if(inputBufferLength < sizeof(LONG))
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			t1394CmdrDebugLevel = *((PLONG)ioBuffer);
		}
		break;
	case IOCTL_GET_CMDR_TRACELEVEL:
		if(outputBufferLength < sizeof(LONG))
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			*((PLONG)ioBuffer) = t1394CmdrDebugLevel;
			Irp->IoStatus.Information = sizeof(LONG);
			
		}
		break;
	case IOCTL_READ_REGISTER:
		{
      if(outputBufferLength < sizeof(REGISTER_IOBUF) ||
	       inputBufferLength < sizeof(REGISTER_IOBUF))
			{
	      ntStatus = STATUS_BUFFER_TOO_SMALL;
			} else {
	      // an address with a leading 0xF will be interpreted
	      // as an absolute offset in register space

	      // otherwise, it will be added to the CSR offset
	      PREGISTER_IOBUF regbuf = (PREGISTER_IOBUF)ioBuffer;
	      ULONG offset = regbuf->ulOffset;

	      if(!(offset & 0xF0000000))
		      offset += deviceExtension->CSR_offset;

	      ntStatus = t1394Cmdr_ReadRegister(DeviceObject,
						      Irp,
						      offset,
						      regbuf->data
						      );
	      if (NT_SUCCESS(ntStatus))
		      Irp->IoStatus.Information = outputBufferLength;
			}
		} break;
	case IOCTL_WRITE_REGISTER:
		{
			if(outputBufferLength < sizeof(REGISTER_IOBUF) ||
	       inputBufferLength < sizeof(REGISTER_IOBUF))
			{
	      ntStatus = STATUS_BUFFER_TOO_SMALL;
			} else {
	      // an address with a leading 0xF will be interpreted
	      // as an absolute offset in register space

	      // otherwise, it will be added to the CSR offset
	      PREGISTER_IOBUF regbuf = (PREGISTER_IOBUF) ioBuffer;
	      ULONG offset = regbuf->ulOffset;

	      if(!(offset & 0xF0000000))
		      offset += deviceExtension->CSR_offset;

	      ntStatus = t1394Cmdr_WriteRegister(DeviceObject,
						       Irp,
						       offset,
						       regbuf->data
						       );
			}
		} break;
	case IOCTL_GET_MODEL_NAME:
		if(outputBufferLength < (unsigned long)(deviceExtension->ModelNameLength))
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			RtlCopyMemory(ioBuffer,&(deviceExtension->pModelLeaf->TL_Data),deviceExtension->ModelNameLength);
			ntStatus = STATUS_SUCCESS;
			Irp->IoStatus.Information = deviceExtension->ModelNameLength;
		}
		break;
	case IOCTL_GET_VENDOR_NAME:
		if(outputBufferLength < (unsigned long)(deviceExtension->VendorNameLength))
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			RtlCopyMemory(ioBuffer,&(deviceExtension->pVendorLeaf->TL_Data),deviceExtension->VendorNameLength);
			ntStatus = STATUS_SUCCESS;
			Irp->IoStatus.Information = deviceExtension->VendorNameLength;
		}
		break;
	case IOCTL_GET_CAMERA_SPECIFICATION:
	
		if(outputBufferLength < sizeof(CAMERA_SPECIFICATION))
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			PCAMERA_SPECIFICATION pSpec = (PCAMERA_SPECIFICATION)(ioBuffer);
			pSpec->ulSpecification = deviceExtension->unit_spec_ID;
			pSpec->ulVersion = deviceExtension->unit_sw_version;
			Irp->IoStatus.Information = sizeof(CAMERA_SPECIFICATION);
		}
		break;

	case IOCTL_GET_CAMERA_UNIQUE_ID:
		if(outputBufferLength < sizeof(LARGE_INTEGER))
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			PLARGE_INTEGER pID = (PLARGE_INTEGER)(ioBuffer);
			pID->HighPart = deviceExtension->pConfigRom->CR_Node_UniqueID[0];
			pID->LowPart = deviceExtension->pConfigRom->CR_Node_UniqueID[1];
			Irp->IoStatus.Information = sizeof(LARGE_INTEGER);
		}
		break;
	case IOCTL_ISOCH_SETUP_STREAM:
		TRACE(TL_TRACE,("IOCTL_ISOCH_SETUP_STREAM\n"));
		if (inputBufferLength < sizeof(ISOCH_STREAM_PARAMS) ||
	      outputBufferLength < sizeof(ISOCH_STREAM_PARAMS) )
		{
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			ntStatus = t1394_IsochSetupStream(DeviceObject,
					Irp,
					(PISOCH_STREAM_PARAMS)ioBuffer);
			if (NT_SUCCESS(ntStatus))
        Irp->IoStatus.Information = outputBufferLength;
		}
		break;
	case IOCTL_ISOCH_TEAR_DOWN_STREAM:
		TRACE(TL_TRACE,("IOCTL_ISOCH_TEAR_DOWN_STREAM\n"));
		ntStatus = t1394_IsochTearDownStream(DeviceObject,Irp);
		break;
	case IOCTL_ATTACH_BUFFER:
		// Input Argument: None
		// Output Argument: The actual buffer as MDL

    // Buffer is good, resources are good, call the function
    // Maybe all this needs to be pushed into t1394Cmdr_IsochAttachBuffer
    ntStatus = t1394Cmdr_IsochAttachBuffer( 
					 DeviceObject,
					 Irp,
					 Irp->MdlAddress
					 );

    if (ntStatus == STATUS_PENDING)
      // Skip IoCompleterequestBelow.  this seems misplaced...
      goto _exit;
		break;
	default:
		TRACE(TL_ERROR, ("Invalid ioControlCode = 0x%x\n", ioControlCode));
		ntStatus = STATUS_INVALID_PARAMETER;
		break; // default

		 

	} // switch

	break; // IRP_MJ_DEVICE_CONTROL

 default:
	 TRACE(TL_TRACE, ("Unknown IrpSp->MajorFunction = 0x%x\n", IrpSp->MajorFunction));

	 // submit this to the driver below us
	 ntStatus = t1394_SubmitIrpAsync (deviceExtension->StackDeviceObject, Irp, NULL);
	 return (ntStatus);
	 break;

} // switch

		// only complete if the device is there
	if (ntStatus != STATUS_NO_SUCH_DEVICE) {
		
		Irp->IoStatus.Status = ntStatus;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
	}

 _exit:

	EXIT("t1394Cmdr_IoControl", ntStatus);
	return(ntStatus);
} // t1394Cmdr_IoControl
Пример #11
0
/**
  Opens a new file relative to the source file's location.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to the source location. This would typically be an open
                     handle to a directory.
  @param  NewHandle  A pointer to the location to return the opened handle for the new
                     file.
  @param  FileName   The Null-terminated string of the name of the file to be opened.
                     The file name may contain the following path modifiers: "\", ".",
                     and "..".
  @param  OpenMode   The mode to open the file. The only valid combinations that the
                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
                     attribute bits for the newly created file.

  @retval EFI_SUCCESS          The file was opened.
  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
                               longer supported.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write
                               when the media is write-protected.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
  @retval EFI_VOLUME_FULL      The volume is full.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemOpen (
  IN     EFI_FILE_PROTOCOL    *This,
     OUT EFI_FILE_PROTOCOL    **NewHandle,
  IN     CHAR16               *FileName,
  IN     UINT64               OpenMode,
  IN     UINT64               Attributes
  )
{
  FV_FILESYSTEM_INSTANCE      *Instance;
  FV_FILESYSTEM_FILE          *File;
  FV_FILESYSTEM_FILE          *NewFile;
  FV_FILESYSTEM_FILE_INFO     *FvFileInfo;
  LIST_ENTRY                  *FvFileInfoLink;
  EFI_STATUS                  Status;
  UINTN                       FileNameLength;
  UINTN                       NewFileNameLength;
  CHAR16                      *FileNameWithExtension;

  //
  // Check for a valid mode
  //
  switch (OpenMode) {
  case EFI_FILE_MODE_READ:
    break;

  default:
    return EFI_WRITE_PROTECTED;
  }

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  FileName = TrimFilePathToAbsolutePath (FileName);
  if (FileName == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (FileName[0] == L'\\') {
    FileName++;
  }

  //
  // Check for opening root
  //
  if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) {
    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (NewFile == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    NewFile->Signature = FVFS_FILE_SIGNATURE;
    NewFile->Instance  = Instance;
    NewFile->FvFileInfo = File->FvFileInfo;
    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    InitializeListHead (&NewFile->Link);
    InsertHeadList (&Instance->FileHead, &NewFile->Link);

    NewFile->DirReadNext = NULL;
    if (!IsListEmpty (&Instance->FileInfoHead)) {
      NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
    }

    *NewHandle = &NewFile->FileProtocol;
    return EFI_SUCCESS;
  }

  //
  // Do a linear search for a file in the FV with a matching filename
  //
  Status     = EFI_NOT_FOUND;
  FvFileInfo = NULL;
  for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
      !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
       FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
    FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
    if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {
      Status = EFI_SUCCESS;
      break;
    }
  }

  // If the file has not been found check if the filename exists with an extension
  // in case there was no extension present.
  // FvFileSystem adds a 'virtual' extension '.EFI' to EFI applications and drivers
  // present in the Firmware Volume
  if (Status == EFI_NOT_FOUND) {
    FileNameLength = StrLen (FileName);

    // Does the filename already contain the '.EFI' extension?
    if (mUnicodeCollation->StriColl (mUnicodeCollation, FileName + FileNameLength - 4, L".efi") != 0) {
      // No, there was no extension. So add one and search again for the file
      // NewFileNameLength = FileNameLength + 1 + 4 = (Number of non-null character) + (file extension) + (a null character)
      NewFileNameLength = FileNameLength + 1 + 4;
      FileNameWithExtension = AllocatePool (NewFileNameLength * 2);
      StrCpyS (FileNameWithExtension, NewFileNameLength, FileName);
      StrCatS (FileNameWithExtension, NewFileNameLength, L".EFI");

      for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
          !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
           FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
        FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
        if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileNameWithExtension) == 0) {
          Status = EFI_SUCCESS;
          break;
        }
      }
    }
  }

  if (!EFI_ERROR (Status)) {
    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (NewFile == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    NewFile->Signature = FVFS_FILE_SIGNATURE;
    NewFile->Instance  = Instance;
    NewFile->FvFileInfo = FvFileInfo;
    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    InitializeListHead (&NewFile->Link);
    InsertHeadList (&Instance->FileHead, &NewFile->Link);

    *NewHandle = &NewFile->FileProtocol;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}
Пример #12
0
NTSTATUS
NTAPI
CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                  IN ULONG OperationType,
                  IN ULONG HiveFlags,
                  IN ULONG FileType,
                  IN PVOID HiveData OPTIONAL,
                  IN HANDLE Primary,
                  IN HANDLE Log,
                  IN HANDLE External,
                  IN PCUNICODE_STRING FileName OPTIONAL,
                  IN ULONG CheckFlags)
{
    PCMHIVE Hive;
    FILE_STANDARD_INFORMATION FileInformation;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_FS_SIZE_INFORMATION FileSizeInformation;
    NTSTATUS Status;
    ULONG Cluster;

    /* Assume failure */
    *RegistryHive = NULL;

    /*
     * The following are invalid:
     * An external hive that is also internal.
     * A log hive that's not a primary hive too.
     * A volatile hive that's linked to permanent storage.
     * An in-memory initialization without hive data.
     * A log hive that's not linked to a correct file type.
     */
    if (((External) && ((Primary) || (Log))) ||
        ((Log) && !(Primary)) ||
        ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
        ((OperationType == HINIT_MEMORY) && (!HiveData)) ||
        ((Log) && (FileType != HFILE_TYPE_LOG)))
    {
        /* Fail the request */
        return STATUS_INVALID_PARAMETER;
    }

    /* Check if this is a primary hive */
    if (Primary)
    {
        /* Get the cluster size */
        Status = ZwQueryVolumeInformationFile(Primary,
                                              &IoStatusBlock,
                                              &FileSizeInformation,
                                              sizeof(FILE_FS_SIZE_INFORMATION),
                                              FileFsSizeInformation);
        if (!NT_SUCCESS(Status)) return Status;

        /* Make sure it's not larger then the block size */
        if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
        {
            /* Fail */
            return STATUS_REGISTRY_IO_FAILED;
        }

        /* Otherwise, calculate the cluster */
        Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
        Cluster = max(1, Cluster);
    }
    else
    {
        /* Otherwise use cluster 1 */
        Cluster = 1;
    }

    /* Allocate the hive */
    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CM);
    if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;

    /* Setup null fields */
    Hive->UnloadEvent = NULL;
    Hive->RootKcb = NULL;
    Hive->Frozen = FALSE;
    Hive->UnloadWorkItem = NULL;
    Hive->GrowOnlyMode = FALSE;
    Hive->GrowOffset = 0;
    Hive->CellRemapArray = NULL;
    Hive->UseCountLog.Next = 0;
    Hive->LockHiveLog.Next = 0;
    Hive->FileObject = NULL;
    Hive->NotifyList.Flink = NULL;
    Hive->NotifyList.Blink = NULL;

    /* Set loading flag */
    Hive->HiveIsLoading = TRUE;

    /* Set the current thread as creator */
    Hive->CreatorOwner = KeGetCurrentThread();

    /* Initialize lists */
    InitializeListHead(&Hive->KcbConvertListHead);
    InitializeListHead(&Hive->KnodeConvertListHead);
    InitializeListHead(&Hive->TrustClassEntry);

    /* Allocate the view log */
    Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(KGUARDED_MUTEX),
                                           TAG_CM);
    if (!Hive->ViewLock)
    {
        /* Cleanup allocation and fail */
        ExFreePoolWithTag(Hive, TAG_CM);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Allocate the flush lock */
    Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                              sizeof(ERESOURCE),
                                              TAG_CM);
    if (!Hive->FlusherLock)
    {
        /* Cleanup allocations and fail */
        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
        ExFreePoolWithTag(Hive, TAG_CM);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Setup the handles */
    Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
    Hive->FileHandles[HFILE_TYPE_LOG] = Log;
    Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External;

    /* Initailize the guarded mutex */
    KeInitializeGuardedMutex(Hive->ViewLock);
    Hive->ViewLockOwner = NULL;

    /* Initialize the flush lock */
    ExInitializeResourceLite(Hive->FlusherLock);

    /* Setup hive locks */
    ExInitializePushLock(&Hive->HiveLock);
    Hive->HiveLockOwner = NULL;
    ExInitializePushLock(&Hive->WriterLock);
    Hive->WriterLockOwner = NULL;
    ExInitializePushLock(&Hive->SecurityLock);
    Hive->HiveSecurityLockOwner = NULL;

    /* Clear file names */
    RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0);
    RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0);

    /* Initialize the view list */
    CmpInitHiveViewList(Hive);

    /* Initailize the security cache */
    CmpInitSecurityCache(Hive);

    /* Setup flags */
    Hive->Flags = 0;
    Hive->FlushCount = 0;

    /* Set flags */
    Hive->Flags = HiveFlags;

    /* Check if this is a primary */
    if (Primary)
    {
        /* Check how large the file is */
        ZwQueryInformationFile(Primary,
                               &IoStatusBlock,
                               &FileInformation,
                               sizeof(FileInformation),
                               FileStandardInformation);
        Cluster = FileInformation.EndOfFile.LowPart;
    }

    /* Initialize it */
    Status = HvInitialize(&Hive->Hive,
                          OperationType,
                          FileType,
                          HiveFlags,
                          HiveData,
                          CmpAllocate,
                          CmpFree,
                          CmpFileSetSize,
                          CmpFileWrite,
                          CmpFileRead,
                          CmpFileFlush,
                          Cluster,
                          FileName);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup allocations and fail */
        ExDeleteResourceLite(Hive->FlusherLock);
        ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
        ExFreePoolWithTag(Hive, TAG_CM);
        return Status;
    }

    /* Check if we should verify the registry */
    if ((OperationType == HINIT_FILE) ||
        (OperationType == HINIT_MEMORY) ||
        (OperationType == HINIT_MEMORY_INPLACE) ||
        (OperationType == HINIT_MAPFILE))
    {
        /* Verify integrity */
        ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags);
        if (CheckStatus != 0)
        {
            /* Cleanup allocations and fail */
            ExDeleteResourceLite(Hive->FlusherLock);
            ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
            ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
            ExFreePoolWithTag(Hive, TAG_CM);
            return STATUS_REGISTRY_CORRUPT;
        }
    }

    /* Lock the hive list */
    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);

    /* Insert this hive */
    InsertHeadList(&CmpHiveListHead, &Hive->HiveList);

    /* Release the lock */
    ExReleasePushLock(&CmpHiveListHeadLock);

    /* Return the hive and success */
    *RegistryHive = (PCMHIVE)Hive;
    return STATUS_SUCCESS;
}
Пример #13
0
NTSTATUS
kmdf1394_FreeAddressRange (
                           IN WDFDEVICE Device,
                           IN WDFREQUEST Request,
                           IN HANDLE hAddressRange)
/*++

Routine Description:

    Allocate Address Range routine.

Arguments:

    Device - the current WDFDEVICE Object.

    Request - the current request.

    hAddressRange - The Address Range to be freed.

Return Value:

    VOID
--*/
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device);
    PIRB pIrb = NULL;
    PASYNC_ADDRESS_DATA AsyncAddressData  = NULL;
    PLIST_ENTRY listHead, thisEntry;

    UNREFERENCED_PARAMETER(Request);

    Enter();

    //
    // have to find our struct...
    //
    WdfSpinLockAcquire (deviceExtension->AsyncSpinLock);

    listHead = &deviceExtension->AsyncAddressData;

    for (thisEntry = listHead->Flink; 
        thisEntry != listHead; 
        AsyncAddressData = NULL, thisEntry = thisEntry->Flink)
    {
        AsyncAddressData = CONTAINING_RECORD (
            thisEntry, 
            ASYNC_ADDRESS_DATA,
            AsyncAddressList);

        if (AsyncAddressData->hAddressRange == hAddressRange) 
        {
            RemoveEntryList(&AsyncAddressData->AsyncAddressList);
            break;
        }
    }

    WdfSpinLockRelease(deviceExtension->AsyncSpinLock);

    //
    // never found an entry...
    //
    if (!AsyncAddressData) 
    {
        return STATUS_INVALID_PARAMETER;
    }

    // 
    // got it, lets free it...
    //
    pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV);
    if (!pIrb) 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_ASYNC, 
                            "Failed to allocate pIrb!\n");

        //
        // Catasrophic failure, insert the AddressData element back on 
        // the list before existing
        //
        WdfSpinLockAcquire (deviceExtension->AsyncSpinLock);

        InsertHeadList (
            &deviceExtension->AsyncAddressData, 
            &AsyncAddressData->AsyncAddressList);

        WdfSpinLockRelease (deviceExtension->AsyncSpinLock);

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_FREE_ADDRESS_RANGE;
    pIrb->Flags = 0;
    pIrb->u.FreeAddressRange.nAddressesToFree = \
        AsyncAddressData->nAddressesReturned;
    pIrb->u.FreeAddressRange.p1394AddressRange = AsyncAddressData->AddressRange;
    pIrb->u.FreeAddressRange.pAddressRange = &AsyncAddressData->hAddressRange;
    pIrb->u.FreeAddressRange.DeviceExtension = (PVOID)deviceExtension;

    //
    // We're going to send this one synchronously
    //
    ntStatus = kmdf1394_SubmitIrpSynch (
        deviceExtension->StackIoTarget, 
        Request, 
        pIrb);
    if (!NT_SUCCESS (ntStatus))
    {
        //
        // The free request failed, insert the element back on to our tracking 
        // list and either try to free later, or release the resources on 
        // driver tear down.
        //
        WdfSpinLockAcquire (deviceExtension->AsyncSpinLock);

        InsertHeadList (
            &deviceExtension->AsyncAddressData, 
            &AsyncAddressData->AsyncAddressList);

        WdfSpinLockRelease (deviceExtension->AsyncSpinLock);
    }
    else
    {
        // 
        //  need to free up everything associated with this from the allocate...
        //
        IoFreeMdl (AsyncAddressData->pMdl);
        ExFreePoolWithTag (AsyncAddressData->Buffer, POOLTAG_KMDF_VDEV);
        ExFreePoolWithTag (AsyncAddressData->AddressRange, POOLTAG_KMDF_VDEV);
        ExFreePoolWithTag (AsyncAddressData, POOLTAG_KMDF_VDEV);
    }

    ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);

    ExitS(ntStatus);
    return ntStatus;
} // kmdf1394_FreeAddressRange
Пример #14
0
VOID  
kmdf1394_AllocateAddressRangeCompletion (    
    IN WDFREQUEST  Request,    
    IN WDFIOTARGET  Target,    
    IN PWDF_REQUEST_COMPLETION_PARAMS  Params,    
    IN WDFCONTEXT  Context)
/*++

Routine Description:

    Allocate Address Range completion routine.

Arguments:

    Request - UNUSED

    Target - UNUSED

    Params - Completion param struct filled out by the completing driver
    
    Context - Pointer to a context structure

Return Value:

    VOID
--*/
{
    PASYNC_ADDRESS_DATA   AsyncAddrData = NULL;
    PALLOCATE_ADDRESS_RANGE  AllocateAddrRange = NULL;
    PDEVICE_EXTENSION  DeviceExtension = NULL;
    WDFMEMORY Memory; 
    PIRB pIrb = NULL;

    PCONTEXT_BUNDLE ContextBundle = NULL;

    //
    // We can get the request completion status from here
    //
    NTSTATUS ntStatus = Params->IoStatus.Status;

    UNREFERENCED_PARAMETER (Target);
    UNREFERENCED_PARAMETER (Request);

    Enter();

    if (NULL == Context)
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_ASYNC, 
                            "Context is NULL!\n");
        return;
    }

    ContextBundle = (PCONTEXT_BUNDLE) Context;


    AllocateAddrRange = (PALLOCATE_ADDRESS_RANGE) ContextBundle->Context0;
    AsyncAddrData = (PASYNC_ADDRESS_DATA) ContextBundle->Context1;
    Memory = (WDFMEMORY) ContextBundle->Context2;
    DeviceExtension = ContextBundle->Context3;

    //
    // By using the WdfMemoryCreatePreallocated, we can pull the pointer to our
    // IRB from the WDFMemory Object.
    //
    pIrb = (PIRB) WdfMemoryGetBuffer (Memory, NULL);

    if (NT_SUCCESS (ntStatus)) 
    {
        AsyncAddrData->nAddressesReturned = \
            pIrb->u.AllocateAddressRange.AddressesReturned;
        AsyncAddrData->hAddressRange = \
            pIrb->u.AllocateAddressRange.hAddressRange;

        WdfSpinLockAcquire (DeviceExtension->AsyncSpinLock);

        InsertHeadList(
            &DeviceExtension->AsyncAddressData, 
            &AsyncAddrData->AsyncAddressList);

        WdfSpinLockRelease(DeviceExtension->AsyncSpinLock);

        AsyncAddrData->hAddressRange = \
            pIrb->u.AllocateAddressRange.hAddressRange;

        //
        // This goes back in to our original packet from user mode
        //
        AllocateAddrRange->hAddressRange = \
            pIrb->u.AllocateAddressRange.hAddressRange;

        AllocateAddrRange->Required1394Offset.Off_High = \
            pIrb->u.AllocateAddressRange.p1394AddressRange[0].AR_Off_High;

        AllocateAddrRange->Required1394Offset.Off_Low = \
            pIrb->u.AllocateAddressRange.p1394AddressRange[0].AR_Off_Low;
    }
    else 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_ASYNC, 
                            "AllocateAddressRange failed = %!STATUS!\n", 
                            ntStatus);

        if (pIrb->u.AllocateAddressRange.Mdl)
        {
            IoFreeMdl (pIrb->u.AllocateAddressRange.Mdl);
        }

        if (AsyncAddrData->Buffer)
        {
            ExFreePoolWithTag (AsyncAddrData->Buffer, POOLTAG_KMDF_VDEV);
        }

        if (AsyncAddrData->AddressRange)
        {
            ExFreePoolWithTag (AsyncAddrData->AddressRange, POOLTAG_KMDF_VDEV);
        }

        ExFreePoolWithTag (AsyncAddrData, POOLTAG_KMDF_VDEV);
    }

    ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);

    WdfObjectDelete (Memory);

    Exit();
}
Пример #15
0
/*************************************************************************
*
* Function: Ext2CommonClose()
*
* Description:
*	The actual work is performed here. This routine may be invoked in one'
*	of the two possible contexts:
*	(a) in the context of a system worker thread
*	(b) in the context of the original caller
*
* Expected Interrupt Level (for execution) :
*
*  IRQL_PASSIVE_LEVEL
*
* Return Value: Does not matter!
*
*************************************************************************/
NTSTATUS NTAPI Ext2CommonClose(
PtrExt2IrpContext			PtrIrpContext,
PIRP						PtrIrp,
BOOLEAN						FirstAttempt )
{
	NTSTATUS					RC = STATUS_SUCCESS;
	PIO_STACK_LOCATION	PtrIoStackLocation = NULL;
	PFILE_OBJECT			PtrFileObject = NULL;
	PtrExt2FCB				PtrFCB = NULL;
	PtrExt2CCB				PtrCCB = NULL;
	PtrExt2VCB				PtrVCB = NULL;
	PtrExt2NTRequiredFCB	PtrReqdFCB = NULL;
	PERESOURCE				PtrResourceAcquired = NULL;
	PERESOURCE				PtrPagingIoResourceAcquired = NULL;

	BOOLEAN					CompleteIrp = TRUE;
	BOOLEAN					PostRequest = FALSE;
	BOOLEAN					AcquiredVCB = FALSE;
	BOOLEAN					BlockForResource;
	int						i = 1;

	try 
	{
		// First, get a pointer to the current I/O stack location
		PtrIoStackLocation = IoGetCurrentIrpStackLocation(PtrIrp);
		ASSERT(PtrIoStackLocation);

		PtrFileObject = PtrIoStackLocation->FileObject;
		ASSERT(PtrFileObject);

		if( !PtrFileObject->FsContext2 )
		{
			//	This must be a Cleanup request received 
			//	as a result of IoCreateStreamFileObject
			//	Only such a File object would have a NULL CCB

			DebugTrace( DEBUG_TRACE_SPECIAL, " === Close with NULL CCB", 0);
			if( PtrFileObject )
			{
				DebugTrace( DEBUG_TRACE_SPECIAL, "###### File Pointer 0x%LX [Close]", PtrFileObject);
			}
			try_return();
		}

		// Get the FCB and CCB pointers

		Ext2GetFCB_CCB_VCB_FromFileObject ( 
			PtrFileObject, &PtrFCB, &PtrCCB, &PtrVCB );

		PtrVCB = (PtrExt2VCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
		ASSERT( PtrVCB );

		if( PtrFCB && PtrFCB->FCBName && PtrFCB->FCBName->ObjectName.Length && PtrFCB->FCBName->ObjectName.Buffer )
		//if( PtrFileObject->FileName.Length && PtrFileObject->FileName.Buffer )
		{
			DebugTrace(DEBUG_TRACE_FILE_NAME, " === Close File Name : -%S-", PtrFCB->FCBName->ObjectName.Buffer );
		}
		else
		{
			DebugTrace(DEBUG_TRACE_FILE_NAME,   " === Close File Name : -null-", 0);
		}

		//	(a) Acquiring the VCBResource Exclusively...
		//	This is done to synchronise with the close and cleanup routines...
//		if( ExTryToAcquireResourceExclusiveLite(&(PtrVCB->VCBResource) ) )

		BlockForResource = !FirstAttempt;
		if( !FirstAttempt )
		{
			DebugTrace(DEBUG_TRACE_MISC, "*** Going into a block to acquire VCB Exclusively [Close]", 0);
		}
		else
		{
			DebugTrace(DEBUG_TRACE_MISC, "*** Attempting to acquire VCB Exclusively [Close]", 0);
		}
		if( PtrFileObject )
		{
			DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
		}

		i = 1;
		while( !AcquiredVCB )
		{
			DebugTraceState( "VCB       AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
			if(! ExAcquireResourceExclusiveLite( &(PtrVCB->VCBResource), FALSE ) )
			{
				DebugTrace(DEBUG_TRACE_MISC,   "*** VCB Acquisition FAILED [Close]", 0);
				if( BlockForResource && i != 1000 )
				{
					LARGE_INTEGER Delay;
					
					//KeSetPriorityThread( PsGetCurrentThread(),LOW_REALTIME_PRIORITY	);

					Delay.QuadPart = -500 * i;
					KeDelayExecutionThread( KernelMode, FALSE, &Delay );
					DebugTrace(DEBUG_TRACE_MISC,  "*** Retrying... after 50 * %ld ms [Close]", i);
				}
				else
				{
					if( i == 1000 )
						DebugTrace(DEBUG_TRACE_MISC,  "*** Reposting... [Close]", 0 );
					PostRequest = TRUE;
					try_return( RC = STATUS_PENDING );
				}
			}
			else
			{
				DebugTrace(DEBUG_TRACE_MISC,  "*** VCB Acquired in [Close]", 0);
				AcquiredVCB = TRUE;
			}
			i *= 10;
		}

		//	(b) Acquire the file (FCB) exclusively
		if( PtrFCB && PtrFCB->NodeIdentifier.NodeType == EXT2_NODE_TYPE_FCB )
		{
			//	This FCB is an FCB indeed. ;)
			//	So acquiring it exclusively...
			//	This is done to synchronise with read/write routines...
			if( !FirstAttempt )
			{
				DebugTrace(DEBUG_TRACE_MISC,   "*** Going into a block to acquire FCB Exclusively [Close]", 0);
			}
			else
			{
				DebugTrace(DEBUG_TRACE_MISC,  "*** Attempting to acquire FCB Exclusively [Close]", 0);
			}
			if( PtrFileObject )
			{
				DebugTrace(DEBUG_TRACE_FILE_OBJ,  "###### File Pointer 0x%LX [Close]", PtrFileObject);
			}

			PtrReqdFCB = &PtrFCB->NTRequiredFCB;

			i = 1;
			while( !PtrResourceAcquired )
			{
				DebugTraceState( "FCBMain   AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]", PtrReqdFCB->MainResource.ActiveCount, PtrReqdFCB->MainResource.NumberOfExclusiveWaiters, PtrReqdFCB->MainResource.NumberOfSharedWaiters );
				if(! ExAcquireResourceExclusiveLite( &(PtrReqdFCB->MainResource), FALSE ) )
				{
					DebugTrace(DEBUG_TRACE_MISC,   "*** FCB Acquisition FAILED [Close]", 0);
					if( BlockForResource && i != 1000 )
					{
						LARGE_INTEGER Delay;
						
						//KeSetPriorityThread( PsGetCurrentThread(),LOW_REALTIME_PRIORITY	);

						Delay.QuadPart = -500 * i;
						KeDelayExecutionThread( KernelMode, FALSE, &Delay );
						DebugTrace(DEBUG_TRACE_MISC,  "*** Retrying... after 50 * %ld ms [Close]", i);
					}
					else
					{
						if( i == 1000 )
							DebugTrace(DEBUG_TRACE_MISC,  "*** Reposting... [Close]", 0 );
						PostRequest = TRUE;
						try_return( RC = STATUS_PENDING );
					}
				}
				else
				{
					DebugTrace(DEBUG_TRACE_MISC,  "*** FCB acquired [Close]", 0);
					PtrResourceAcquired = & ( PtrReqdFCB->MainResource );
				}
				i *= 10;
			}

			i = 1;
			while( !PtrPagingIoResourceAcquired )
			{
				DebugTraceState( "FCBPaging   AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]", PtrReqdFCB->PagingIoResource.ActiveCount, PtrReqdFCB->PagingIoResource.NumberOfExclusiveWaiters, PtrReqdFCB->PagingIoResource.NumberOfSharedWaiters );
				if(! ExAcquireResourceExclusiveLite( &(PtrReqdFCB->PagingIoResource), FALSE ) )
				{
					DebugTrace(DEBUG_TRACE_MISC,   "*** FCB Acquisition FAILED [Close]", 0);
					if( BlockForResource && i != 1000 )
					{
						LARGE_INTEGER Delay;
						
						// KeSetPriorityThread( PsGetCurrentThread(), LOW_REALTIME_PRIORITY );

						Delay.QuadPart = -500 * i;
						KeDelayExecutionThread( KernelMode, FALSE, &Delay );
						DebugTrace(DEBUG_TRACE_MISC,  "*** Retrying... after 50 * %ld ms [Close]", i);
					}
					else
					{
						if( i == 1000 )
							DebugTrace(DEBUG_TRACE_MISC,  "*** Reposting... [Close]", 0 );
						PostRequest = TRUE;
						try_return( RC = STATUS_PENDING );
					}
				}
				else
				{
					DebugTrace(DEBUG_TRACE_MISC,  "*** FCB acquired [Close]", 0);
					PtrPagingIoResourceAcquired = & ( PtrReqdFCB->PagingIoResource );
				}
				i *= 10;
			}

			// (c) Delete the CCB structure (free memory)
			RemoveEntryList( &PtrCCB->NextCCB );
			Ext2ReleaseCCB( PtrCCB );
			PtrFileObject->FsContext2 = NULL;

			// (d) Decrementing the Reference Count...
			if( PtrFCB->ReferenceCount )
			{
				InterlockedDecrement( &PtrFCB->ReferenceCount );
			}
			else
			{
				Ext2BreakPoint();
			}	
			DebugTrace(DEBUG_TRACE_REFERENCE,  "^^^^^ReferenceCount = 0x%lX [Close]", PtrFCB->ReferenceCount );
			DebugTrace(DEBUG_TRACE_REFERENCE,  "^^^^^OpenHandleCount = 0x%lX [Close]", PtrFCB->OpenHandleCount );
			if( PtrFCB->ReferenceCount == 0 )
			{

				//	Attempting to update time stamp values
				//	Errors are ignored...
				//	Not considered as critical errors...
				
				{
					ULONG			CreationTime, AccessTime, ModificationTime;
					EXT2_INODE		Inode;

					CreationTime = (ULONG) ( (PtrFCB->CreationTime.QuadPart 
									- Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
					AccessTime = (ULONG) ( (PtrFCB->LastAccessTime.QuadPart 
									- Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
					ModificationTime = (ULONG) ( (PtrFCB->LastWriteTime.QuadPart
									- Ext2GlobalData.TimeDiff.QuadPart) / 10000000 );
					if( NT_SUCCESS( Ext2ReadInode( PtrVCB, PtrFCB->INodeNo, &Inode ) ) )
					{
						//	Update time stamps in the inode...
						Inode.i_ctime = CreationTime;
						Inode.i_atime = AccessTime;
						Inode.i_mtime = ModificationTime;

						//	Updating the inode...
						Ext2WriteInode( NULL, PtrVCB, PtrFCB->INodeNo, &Inode );
					}
				}


				if( PtrFCB->INodeNo == EXT2_ROOT_INO )
				{
					//
					//	Root Directory FCB
					//	Preserve this
					//	FSD has a File Object for this FCB...
					//
					DebugTrace(DEBUG_TRACE_MISC,  "^^^^^Root Directory FCB ; leaveing it alone[Close]", 0);
					//	Do nothing...
					
				}
				else if( PtrFCB->DcbFcb.Dcb.PtrDirFileObject )
				{
					//
					//	If this is a FCB created on the FSD's initiative
					//	Leave it alone
					//
					DebugTrace(DEBUG_TRACE_MISC,  "^^^^^FCB Created  on the FSD's initiative; leaveing it alone[Close]", 0);
					if( !PtrFCB->ClosableFCBs.OnClosableFCBList )
					{
						InsertTailList( &PtrVCB->ClosableFCBs.ClosableFCBListHead,
							&PtrFCB->ClosableFCBs.ClosableFCBList );
						PtrVCB->ClosableFCBs.Count++;

						PtrFCB->ClosableFCBs.OnClosableFCBList = TRUE;
					}
					
					if( PtrVCB->ClosableFCBs.Count > EXT2_MAXCLOSABLE_FCBS_UL )
					{
						PtrExt2FCB		PtrTempFCB = NULL;
						//	Checking if Closable FCBs are too many in number...
						//	Shouldn't block the 
						//	Should do this asynchronously...
						//	Maybe later...
						PLIST_ENTRY		PtrEntry = NULL;

						PtrEntry = RemoveHeadList( &PtrVCB->ClosableFCBs.ClosableFCBListHead );
						
						PtrTempFCB = CONTAINING_RECORD( PtrEntry, Ext2FCB, ClosableFCBs.ClosableFCBList );
						if( Ext2CloseClosableFCB( PtrTempFCB ) )
						{
							DebugTrace( DEBUG_TRACE_FREE, "Freeing  = %lX [Close]", PtrTempFCB );
							ExFreePool( PtrTempFCB );
							PtrVCB->ClosableFCBs.Count--;
						}
						else
						{
							//	Put the FCB back in the list...
							InsertHeadList( &PtrVCB->ClosableFCBs.ClosableFCBListHead,
								&PtrTempFCB->ClosableFCBs.ClosableFCBList );
						}
						DebugTrace( DEBUG_TRACE_SPECIAL, "ClosableFCBs Count = %ld [Close]", PtrVCB->ClosableFCBs.Count );
					}
				}
				else
				{
					//	Remove this FCB as well...
					DebugTrace(DEBUG_TRACE_MISC,  "^^^^^Deleting FCB  [Close]", 0);
					RemoveEntryList( &PtrFCB->NextFCB );

					if ( PtrPagingIoResourceAcquired )
					{
						Ext2ReleaseResource(PtrPagingIoResourceAcquired);
						DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
							PtrPagingIoResourceAcquired->ActiveCount, 
							PtrPagingIoResourceAcquired->NumberOfExclusiveWaiters, 
							PtrPagingIoResourceAcquired->NumberOfSharedWaiters );

						PtrPagingIoResourceAcquired = NULL;
					}

					if ( PtrResourceAcquired ) 
					{
						Ext2ReleaseResource(PtrResourceAcquired);
						DebugTrace(DEBUG_TRACE_MISC,  "*** FCB Released [Close]", 0);
						DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
							PtrResourceAcquired->ActiveCount, 
							PtrResourceAcquired->NumberOfExclusiveWaiters, 
							PtrResourceAcquired->NumberOfSharedWaiters );

						if( PtrFileObject )
						{
							DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
						}
						PtrResourceAcquired = NULL;
					}

					Ext2ReleaseFCB( PtrFCB );
				}

			}
			CompleteIrp = TRUE;
		}
		else
		{
			//	This must be a volume close...
			//	What do I do now? ;)
			DebugTrace(DEBUG_TRACE_MISC,   "VCB Close Requested !!!", 0);
			CompleteIrp = TRUE;
		}
		try_return();
		
		try_exit:	NOTHING;

	} 
	finally 
	{
		if ( PtrPagingIoResourceAcquired )
		{
			Ext2ReleaseResource(PtrPagingIoResourceAcquired);
			DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
				PtrPagingIoResourceAcquired->ActiveCount,
				PtrPagingIoResourceAcquired->NumberOfExclusiveWaiters,
				PtrPagingIoResourceAcquired->NumberOfSharedWaiters );

			PtrPagingIoResourceAcquired = NULL;
		}

		if ( PtrResourceAcquired ) 
		{
			Ext2ReleaseResource(PtrResourceAcquired);
			DebugTrace(DEBUG_TRACE_MISC,  "*** FCB Released [Close]", 0);
			DebugTraceState( "Resource     AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]",
				PtrResourceAcquired->ActiveCount, 
				PtrResourceAcquired->NumberOfExclusiveWaiters, 
				PtrResourceAcquired->NumberOfSharedWaiters );

			if( PtrFileObject )
			{
				DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
			}
			PtrResourceAcquired = NULL;
		}

		if (AcquiredVCB) 
		{
			ASSERT(PtrVCB);
			Ext2ReleaseResource(&(PtrVCB->VCBResource));
			DebugTraceState( "VCB       AC:0x%LX   EX:0x%LX   SW:0x%LX   [Close]", PtrVCB->VCBResource.ActiveCount, PtrVCB->VCBResource.NumberOfExclusiveWaiters, PtrVCB->VCBResource.NumberOfSharedWaiters );
			DebugTrace(DEBUG_TRACE_MISC,   "*** VCB Released [Close]", 0);

			AcquiredVCB = FALSE;
			if( PtrFileObject )
			{
				DebugTrace(DEBUG_TRACE_FILE_OBJ, "###### File Pointer 0x%LX [Close]", PtrFileObject);
			}
			
		}

		if( PostRequest )
		{
			RC = Ext2PostRequest(PtrIrpContext, PtrIrp);
		}
		else if( CompleteIrp && RC != STATUS_PENDING )
		{
			// complete the IRP
			IoCompleteRequest( PtrIrp, IO_DISK_INCREMENT );

			Ext2ReleaseIrpContext( PtrIrpContext );
		}

	} // end of "finally" processing

	return(RC);
}
Пример #16
0
BOOLEAN
BlReadSignature(
    IN PCHAR DiskName,
    IN BOOLEAN IsCdRom
    )

/*++

Routine Description:

    Given an ARC disk name, reads the MBR and adds its signature to the list of
    disks.

Arguments:

    Diskname - Supplies the name of the disk.

    IsCdRom - Indicates whether the disk is a CD-ROM.

Return Value:

    TRUE - Success

    FALSE - Failure

--*/

{
    PARC_DISK_SIGNATURE Signature;
    UCHAR SectorBuffer[2048+256];
    UCHAR Partition[100];
    ULONG DiskId;
    ULONG Status;
    LARGE_INTEGER SeekValue;
    PUCHAR Sector;
    ULONG i;
    ULONG Sum;
    ULONG Count;
    ULONG SectorSize;

    if (IsCdRom) {
        SectorSize = 2048;
    } else {
        SectorSize = 512;
    }

    Signature = BlAllocateHeap(sizeof(ARC_DISK_SIGNATURE));
    if (Signature==NULL) {
        return(FALSE);
    }

    Signature->ArcName = BlAllocateHeap(strlen(DiskName)+2);
    if (Signature->ArcName==NULL) {
        return(FALSE);
    }
#if defined(_X86_)
    //
    // NTDETECT creates an "eisa(0)..." arcname for detected
    // BIOS disks on an EISA machine.  Change this to "multi(0)..."
    // in order to be consistent with the rest of the system
    // (particularly the arcname in boot.ini)
    //
    if (_strnicmp(DiskName,"eisa",4)==0) {
        strcpy(Signature->ArcName,"multi");
        strcpy(Partition,"multi");
        strcat(Signature->ArcName,DiskName+4);
        strcat(Partition,DiskName+4);
    } else {
        strcpy(Signature->ArcName, DiskName);
        strcpy(Partition, DiskName);
    }
#else
    strcpy(Signature->ArcName, DiskName);
    strcpy(Partition, DiskName);
#endif

    strcat(Partition, "partition(0)");

    Status = ArcOpen(Partition, ArcOpenReadOnly, &DiskId);
    if (Status != ESUCCESS) {
        return(TRUE);
    }

    //
    // Read in the first sector
    //
    Sector = ALIGN_BUFFER(SectorBuffer);
    if (IsCdRom) {
        //
        // For a CD-ROM, the interesting data starts at 0x8000.
        //
        SeekValue.QuadPart = 0x8000;
    } else {
        SeekValue.QuadPart = 0;
    }
    Status = ArcSeek(DiskId, &SeekValue, SeekAbsolute);
    if (Status == ESUCCESS) {
        Status = ArcRead(DiskId,
                         Sector,
                         SectorSize,
                         &Count);
    }
    ArcClose(DiskId);
    if (Status != ESUCCESS) {
        return(TRUE);
    }

    //
    // Check to see whether this disk has a valid partition table signature or not.
    //
    if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) {
        Signature->ValidPartitionTable = FALSE;
    } else {
        Signature->ValidPartitionTable = TRUE;
    }

    Signature->Signature = ((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1];

    //
    // compute the checksum
    //
    Sum = 0;
    for (i=0; i<(SectorSize/4); i++) {
        Sum += ((PULONG)Sector)[i];
    }
    Signature->CheckSum = ~Sum + 1;

    InsertHeadList(&BlLoaderBlock->ArcDiskInformation->DiskSignatures,
                   &Signature->ListEntry);

    return(TRUE);

}
Пример #17
0
/**
  Provides the controller-specific addresses required to access system memory
  from a DMA bus master. On SEV guest, the DMA operations must be performed on
  shared buffer hence we allocate a bounce buffer to map the HostAddress to a
  DeviceAddress. The Encryption attribute is removed from the DeviceAddress
  buffer.

  @param  This                  The protocol instance pointer.
  @param  Operation             Indicates if the bus master is going to read or
                                write to system memory.
  @param  HostAddress           The system memory address to map to the PCI
                                controller.
  @param  NumberOfBytes         On input the number of bytes to map. On output
                                the number of bytes that were mapped.
  @param  DeviceAddress         The resulting map address for the bus master
                                PCI controller to use to access the hosts
                                HostAddress.
  @param  Mapping               A resulting value to pass to Unmap().

  @retval EFI_SUCCESS           The range was mapped for the returned
                                NumberOfBytes.
  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common
                                buffer.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a
                                lack of resources.
  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested
                                address.

**/
EFI_STATUS
EFIAPI
IoMmuMap (
  IN     EDKII_IOMMU_PROTOCOL                       *This,
  IN     EDKII_IOMMU_OPERATION                      Operation,
  IN     VOID                                       *HostAddress,
  IN OUT UINTN                                      *NumberOfBytes,
  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
  OUT    VOID                                       **Mapping
  )
{
  EFI_STATUS                                        Status;
  MAP_INFO                                          *MapInfo;
  EFI_ALLOCATE_TYPE                                 AllocateType;
  COMMON_BUFFER_HEADER                              *CommonBufferHeader;
  VOID                                              *DecryptionSource;

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: Operation=%a Host=0x%p Bytes=0x%Lx\n",
    __FUNCTION__,
    ((Operation >= 0 &&
      Operation < ARRAY_SIZE (mBusMasterOperationName)) ?
     mBusMasterOperationName[Operation] :
     "Invalid"),
    HostAddress,
    (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes)
    ));

  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL ||
      Mapping == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
  // called later.
  //
  MapInfo = AllocatePool (sizeof (MAP_INFO));
  if (MapInfo == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Failed;
  }

  //
  // Initialize the MAP_INFO structure, except the PlainTextAddress field
  //
  ZeroMem (&MapInfo->Link, sizeof MapInfo->Link);
  MapInfo->Signature         = MAP_INFO_SIG;
  MapInfo->Operation         = Operation;
  MapInfo->NumberOfBytes     = *NumberOfBytes;
  MapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
  MapInfo->CryptedAddress    = (UINTN)HostAddress;

  //
  // In the switch statement below, we point "MapInfo->PlainTextAddress" to the
  // plaintext buffer, according to Operation. We also set "DecryptionSource".
  //
  MapInfo->PlainTextAddress = MAX_ADDRESS;
  AllocateType = AllocateAnyPages;
  DecryptionSource = (VOID *)(UINTN)MapInfo->CryptedAddress;
  switch (Operation) {
  //
  // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer
  // is necessary regardless of whether the original (crypted) buffer crosses
  // the 4GB limit or not -- we have to allocate a separate plaintext buffer.
  // The only variable is whether the plaintext buffer should be under 4GB.
  //
  case EdkiiIoMmuOperationBusMasterRead:
  case EdkiiIoMmuOperationBusMasterWrite:
    MapInfo->PlainTextAddress = BASE_4GB - 1;
    AllocateType = AllocateMaxAddress;
    //
    // fall through
    //
  case EdkiiIoMmuOperationBusMasterRead64:
  case EdkiiIoMmuOperationBusMasterWrite64:
    //
    // Allocate the implicit plaintext bounce buffer.
    //
    Status = gBS->AllocatePages (
                    AllocateType,
                    EfiBootServicesData,
                    MapInfo->NumberOfPages,
                    &MapInfo->PlainTextAddress
                    );
    if (EFI_ERROR (Status)) {
      goto FreeMapInfo;
    }
    break;

  //
  // For BusMasterCommonBuffer[64] operations, a to-be-plaintext buffer and a
  // stash buffer (for in-place decryption) have been allocated already, with
  // AllocateBuffer(). We only check whether the address of the to-be-plaintext
  // buffer is low enough for the requested operation.
  //
  case EdkiiIoMmuOperationBusMasterCommonBuffer:
    if ((MapInfo->CryptedAddress > BASE_4GB) ||
        (EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages) >
         BASE_4GB - MapInfo->CryptedAddress)) {
      //
      // CommonBuffer operations cannot be remapped. If the common buffer is
      // above 4GB, then it is not possible to generate a mapping, so return an
      // error.
      //
      Status = EFI_UNSUPPORTED;
      goto FreeMapInfo;
    }
    //
    // fall through
    //
  case EdkiiIoMmuOperationBusMasterCommonBuffer64:
    //
    // The buffer at MapInfo->CryptedAddress comes from AllocateBuffer().
    //
    MapInfo->PlainTextAddress = MapInfo->CryptedAddress;
    //
    // Stash the crypted data.
    //
    CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
                           (UINTN)MapInfo->CryptedAddress - EFI_PAGE_SIZE
                           );
    ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
    CopyMem (
      CommonBufferHeader->StashBuffer,
      (VOID *)(UINTN)MapInfo->CryptedAddress,
      MapInfo->NumberOfBytes
      );
    //
    // Point "DecryptionSource" to the stash buffer so that we decrypt
    // it to the original location, after the switch statement.
    //
    DecryptionSource = CommonBufferHeader->StashBuffer;
    break;

  default:
    //
    // Operation is invalid
    //
    Status = EFI_INVALID_PARAMETER;
    goto FreeMapInfo;
  }

  //
  // Clear the memory encryption mask on the plaintext buffer.
  //
  Status = MemEncryptSevClearPageEncMask (
             0,
             MapInfo->PlainTextAddress,
             MapInfo->NumberOfPages,
             TRUE
             );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    CpuDeadLoop ();
  }

  //
  // If this is a read operation from the Bus Master's point of view,
  // then copy the contents of the real buffer into the mapped buffer
  // so the Bus Master can read the contents of the real buffer.
  //
  // For BusMasterCommonBuffer[64] operations, the CopyMem() below will decrypt
  // the original data (from the stash buffer) back to the original location.
  //
  if (Operation == EdkiiIoMmuOperationBusMasterRead ||
      Operation == EdkiiIoMmuOperationBusMasterRead64 ||
      Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
      Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
    CopyMem (
      (VOID *) (UINTN) MapInfo->PlainTextAddress,
      DecryptionSource,
      MapInfo->NumberOfBytes
      );
  }

  //
  // Track all MAP_INFO structures.
  //
  InsertHeadList (&mMapInfos, &MapInfo->Link);
  //
  // Populate output parameters.
  //
  *DeviceAddress = MapInfo->PlainTextAddress;
  *Mapping       = MapInfo;

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: Mapping=0x%p Device(PlainText)=0x%Lx Crypted=0x%Lx Pages=0x%Lx\n",
    __FUNCTION__,
    MapInfo,
    MapInfo->PlainTextAddress,
    MapInfo->CryptedAddress,
    (UINT64)MapInfo->NumberOfPages
    ));

  return EFI_SUCCESS;

FreeMapInfo:
  FreePool (MapInfo);

Failed:
  *NumberOfBytes = 0;
  return Status;
}
Пример #18
0
VOID
RedirDataGramNotifierThreadProc (
	IN PLFSDGRAMNTC_CTX	NtcCtx
	) 
{
	NTSTATUS			status;
	LFSDG_Socket		DGBcastSocket;
	PLIST_ENTRY			listEntry;
	LARGE_INTEGER		TimeOut;
	LPX_ADDRESS			BroadcastAddr;
	PLFSDG_PKT			Dgpkt;
	PLFSTAB_ENTRY		LfsTableEntry;
	KIRQL				oldIrql;
	BOOLEAN				bRet;
	LONG				NetEvent;

	SPY_LOG_PRINT( LFS_DEBUG_LIB_INFO, ("[LFS] DataGramNotifier: Initializing Datagram broadcaster...\n") );

	// Open server datagram port

	status = LfsOpenDGSocket( &DGBcastSocket, 0 );

	BroadcastAddr.Node[0] = 0xFF;
	BroadcastAddr.Node[1] = 0xFF;
	BroadcastAddr.Node[2] = 0xFF;
	BroadcastAddr.Node[3] = 0xFF;
	BroadcastAddr.Node[4] = 0xFF;
	BroadcastAddr.Node[5] = 0xFF;
	BroadcastAddr.Port = HTONS(DEFAULT_DATAGRAM_SVRPORT);

	SPY_LOG_PRINT( LFS_DEBUG_LIB_INFO, ("[LFS] DataGramNotifier: Redirection Datagram server started...\n") );

	// Main loop...

	do {

		TimeOut.QuadPart = - DGNOTIFICATION_FREQ;
		
		status = KeWaitForSingleObject( &NtcCtx->ShutdownEvent,
										Executive,
										KernelMode,
										FALSE,
										&TimeOut );

		SPY_LOG_PRINT( LFS_DEBUG_LIB_NOISE, ( "[LFS] DataGramNotifier: NTSTATUS:%lu\n", status) );
		
		if (status == 0) {

			SPY_LOG_PRINT( LFS_DEBUG_LIB_INFO, 
						   ("[LFS] DataGramNotifier: ShutDown event received. NTSTATUS:%lu\n", status) );
			break;

		} else if (status == STATUS_TIMEOUT) {
		
			//	Time Out.
		
			SPY_LOG_PRINT( LFS_DEBUG_LIB_NOISE, 
						   ("[LFS] DataGramNotifier: ShutDown event time out. Go ahead and broadcast. NTSTATUS:%lu\n", 
						    status) );
		
		} else {

			NDAS_ASSERT( FALSE );
			break;
		}

		//	check to see if network event arise.

		NetEvent = InterlockedExchange( &NtcCtx->NetEvt, 0 );

		if (NetEvent) {

			SPY_LOG_PRINT( LFS_DEBUG_LIB_NOISE, ("DataGramNotifier: Renew the socket.\n") );

			//	renew the socket.
			
			LfsCloseDGSocket( &DGBcastSocket );

			status = LfsOpenDGSocket( &DGBcastSocket, 0 );

			if (status != STATUS_SUCCESS) {
			
				LARGE_INTEGER	interval;

				SPY_LOG_PRINT( LFS_DEBUG_LIB_INFO, 
							   ("DataGramNotifier: could not renew the socket. NTSTATUS:%08lx\n", status) );

				interval.QuadPart = -NANO100_PER_SEC;
				KeDelayExecutionThread(KernelMode, FALSE, &interval);
		
				continue;
			}
		}

		//	traverse through to make up broadcast messages.

		KeAcquireSpinLock( &NtcCtx->LfsTable->SpinLock, &oldIrql );

		listEntry = NtcCtx->LfsTable->LfsTabPartitionList.Flink;

		while (listEntry != &NtcCtx->LfsTable->LfsTabPartitionList) {

			LfsTableEntry = CONTAINING_RECORD(listEntry, LFSTAB_ENTRY, LfsTabPartitionEntry );
			listEntry = listEntry->Flink;

			//	If this host is primary for the NDAS device,
			//	broadcast it.

			if (!FlagOn(LfsTableEntry->Flags, LFSTABENTRY_FLAG_ACTPRIMARY)) {

				continue;
			}

			SPY_LOG_PRINT( LFS_DEBUG_LIB_NOISE, 
						   ("DataGramNotifier: broadcast NetDisk: %02x:%02x:%02x:%02x:%02x:%02x/%d UD:%d\n", 
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node[0],
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node[1],
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node[2],
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node[3],
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node[4],
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node[5],
							 NTOHS(LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Port),
							 LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.UnitDiskNo) );

			bRet = LfsAllocDGPkt( &Dgpkt, sizeof(NDFT_PRIMARY_UPDATE) );

			if (bRet == FALSE) {

				NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES );
				continue;
			}

			//	Initialize the datagram packet.
			//	We do not use owner's network address.
			//	datagram packet receiving handler must be possible to 
			//  retrieve the sender's address(owner's network address).
			
			Dgpkt->RawHeadDG.Type2 = HTONS( LFSPKTTYPE_DATAGRAM | LFSPKTTYPE_REQUEST | NDFT_PRIMARY_UPDATE_MESSAGE );
			
			RtlCopyMemory( Dgpkt->RawDataDG.Owner.NetDiskNode,
						   LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Node,
						   ETHER_ADDR_LENGTH );

			Dgpkt->RawDataDG.Owner.NetDiskPort = LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NetdiskAddress.Port;
			Dgpkt->RawDataDG.Owner.UnitDiskNo = LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.UnitDiskNo;

			RtlCopyMemory( Dgpkt->RawDataDG.Owner.NdscId,
						   LfsTableEntry->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.NdscId,
						   NDSC_ID_LENGTH );

			Dgpkt->RawDataDG.Owner.PrimaryPort = HTONS(DEFAULT_PRIMARY_PORT);

			//	Insert SendPkts Queue

			InsertHeadList( &NtcCtx->SendPkts, &Dgpkt->PktListEntry );
		}

		KeReleaseSpinLock( &NtcCtx->LfsTable->SpinLock, oldIrql );

		//	send notification messages by broadcast.

		while (!IsListEmpty(&NtcCtx->SendPkts)) {
			
			LPX_ADDRESS			NetDiskAddress;
			LPX_ADDRESS			PrimaryAddress;
			PNDFT_HEADER		RawHead;
			PLFSDG_RAWPKT_DATA	RawData;

			UINT8				NdscId[NDSC_ID_LENGTH];

			listEntry = RemoveHeadList(&NtcCtx->SendPkts);
			Dgpkt = CONTAINING_RECORD(listEntry, LFSDG_PKT, PktListEntry);

			status = LfsSendDatagram( &DGBcastSocket, Dgpkt, &BroadcastAddr );

			if (status != STATUS_SUCCESS) {
			
				SPY_LOG_PRINT( LFS_DEBUG_LIB_INFO, ( "[LFS] DataGramNotifier: LfsSendDatagram() failed.\n") );
				NDAS_ASSERT( NDAS_ASSERT_NETWORK_FAIL );
			}

			//	NDIS in Windows Server 2003 doesn't seem to support loopback of broadcasting packets.
			//	Update NetDisk table here.

			RawHead = &Dgpkt->RawHeadDG;
			RawData = &Dgpkt->RawDataDG;

			RtlCopyMemory(NetDiskAddress.Node, RawData->Owner.NetDiskNode, ETHER_ADDR_LENGTH);
			NetDiskAddress.Port = RawData->Owner.NetDiskPort;

			RtlCopyMemory( NdscId, RawData->Owner.NdscId, NDSC_ID_LENGTH );

			RtlCopyMemory(PrimaryAddress.Node, Dgpkt->SourceAddr.Node, ETHER_ADDR_LENGTH);
			PrimaryAddress.Port = RawData->Owner.PrimaryPort;

			SPY_LOG_PRINT( LFS_DEBUG_LIB_NOISE, 
						   ("[LFS] RedirDataGramNotifierThread: updating %02x:%02x:%02x:%02x:%02x:%02x/%d.\n",
							NetDiskAddress.Node[0], NetDiskAddress.Node[1], NetDiskAddress.Node[2],
							NetDiskAddress.Node[3], NetDiskAddress.Node[4], NetDiskAddress.Node[5],
							NTOHS(NetDiskAddress.Port)) );

			LfsTable_UpdatePrimaryInfo( NtcCtx->LfsTable, 
										&NetDiskAddress, 
										(UCHAR)RawData->Owner.UnitDiskNo, 
										&PrimaryAddress, 
										NdscId );

			//	Because LfsSendDatagram() is a synchronous I/O function,
			//	we can dereference the pkt here.
	
			LfsDereferenceDGPkt( Dgpkt );
		}
	
	} while (1);

	LfsCloseDGSocket( &DGBcastSocket );

	SPY_LOG_PRINT( LFS_DEBUG_LIB_INFO, ( "[LFS] DataGramNotifier: terminated..\n") );

	PsTerminateSystemThread( 0 );

	return;
}
Пример #19
0
/**
  Get selection for OneOf and OrderedList (Left/Right will be ignored).

  @param  Selection         Pointer to current selection.
  @param  MenuOption        Pointer to the current input menu.

  @retval EFI_SUCCESS       If Option input is processed successfully
  @retval EFI_DEVICE_ERROR  If operation fails

**/
EFI_STATUS
GetSelectionInputPopUp (
  IN  UI_MENU_SELECTION           *Selection,
  IN  UI_MENU_OPTION              *MenuOption
  )
{
  EFI_STATUS              Status;
  EFI_INPUT_KEY           Key;
  UINTN                   Index;
  CHAR16                  *StringPtr;
  CHAR16                  *TempStringPtr;
  UINTN                   Index2;
  UINTN                   TopOptionIndex;
  UINTN                   HighlightOptionIndex;
  UINTN                   Start;
  UINTN                   End;
  UINTN                   Top;
  UINTN                   Bottom;
  UINTN                   PopUpMenuLines;
  UINTN                   MenuLinesInView;
  UINTN                   PopUpWidth;
  CHAR16                  Character;
  INT32                   SavedAttribute;
  BOOLEAN                 ShowDownArrow;
  BOOLEAN                 ShowUpArrow;
  UINTN                   DimensionsWidth;
  LIST_ENTRY              *Link;
  BOOLEAN                 OrderedList;
  UINT8                   *ValueArray;
  UINT8                   ValueType;
  EFI_HII_VALUE           HiiValue;
  EFI_HII_VALUE           *HiiValueArray;
  UINTN                   OptionCount;
  QUESTION_OPTION         *OneOfOption;
  QUESTION_OPTION         *CurrentOption;
  FORM_BROWSER_STATEMENT  *Question;
  INTN                    Result;

  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

  ValueArray        = NULL;
  ValueType         = 0;
  CurrentOption     = NULL;
  ShowDownArrow     = FALSE;
  ShowUpArrow       = FALSE;

  StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);
  ASSERT (StringPtr);

  Question = MenuOption->ThisTag;
  if (Question->Operand == EFI_IFR_ORDERED_LIST_OP) {
    ValueArray = Question->BufferValue;
    ValueType = Question->ValueType;
    OrderedList = TRUE;
  } else {
    OrderedList = FALSE;
  }

  //
  // Calculate Option count
  //
  if (OrderedList) {
    for (Index = 0; Index < Question->MaxContainers; Index++) {
      if (GetArrayData (ValueArray, ValueType, Index) == 0) {
        break;
      }
    }

    OptionCount = Index;
  } else {
    OptionCount = 0;
    Link = GetFirstNode (&Question->OptionListHead);
    while (!IsNull (&Question->OptionListHead, Link)) {
      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

      OptionCount++;

      Link = GetNextNode (&Question->OptionListHead, Link);
    }
  }

  //
  // Prepare HiiValue array
  //
  HiiValueArray = AllocateZeroPool (OptionCount * sizeof (EFI_HII_VALUE));
  ASSERT (HiiValueArray != NULL);
  Link = GetFirstNode (&Question->OptionListHead);
  for (Index = 0; Index < OptionCount; Index++) {
    if (OrderedList) {
      HiiValueArray[Index].Type = ValueType;
      HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);
    } else {
      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
      CopyMem (&HiiValueArray[Index], &OneOfOption->Value, sizeof (EFI_HII_VALUE));
      Link = GetNextNode (&Question->OptionListHead, Link);
    }
  }

  //
  // Move Suppressed Option to list tail
  //
  PopUpMenuLines = 0;
  for (Index = 0; Index < OptionCount; Index++) {
    OneOfOption = ValueToOption (Question, &HiiValueArray[OptionCount - Index - 1]);
    if (OneOfOption == NULL) {
      return EFI_NOT_FOUND;
    }

    RemoveEntryList (&OneOfOption->Link);

    if ((OneOfOption->SuppressExpression != NULL) &&
        EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {
      //
      // This option is suppressed, insert to tail
      //
      InsertTailList (&Question->OptionListHead, &OneOfOption->Link);
    } else {
      //
      // Insert to head
      //
      InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);

      PopUpMenuLines++;
    }
  }

  //
  // Get the number of one of options present and its size
  //
  PopUpWidth = 0;
  HighlightOptionIndex = 0;
  Link = GetFirstNode (&Question->OptionListHead);
  for (Index = 0; Index < PopUpMenuLines; Index++) {
    OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

    StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
    if (StrLen (StringPtr) > PopUpWidth) {
      PopUpWidth = StrLen (StringPtr);
    }
    FreePool (StringPtr);

    if (!OrderedList && (CompareHiiValue (&Question->HiiValue, &OneOfOption->Value, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
      //
      // Find current selected Option for OneOf
      //
      HighlightOptionIndex = Index;
    }

    Link = GetNextNode (&Question->OptionListHead, Link);
  }

  //
  // Perform popup menu initialization.
  //
  PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;

  SavedAttribute = gST->ConOut->Mode->Attribute;
  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {
    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;
  }

  Start  = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;
  End    = Start + PopUpWidth + POPUP_FRAME_WIDTH;
  Top    = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;
  Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - 1;

  MenuLinesInView = Bottom - Top - 1;
  if (MenuLinesInView >= PopUpMenuLines) {
    Top     = Top + (MenuLinesInView - PopUpMenuLines) / 2;
    Bottom  = Top + PopUpMenuLines + 1;
  } else {
    ShowDownArrow = TRUE;
  }

  if (HighlightOptionIndex > (MenuLinesInView - 1)) {
    TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1;
  } else {
    TopOptionIndex = 0;
  }

  do {
    //
    // Clear that portion of the screen
    //
    ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);

    //
    // Draw "One of" pop-up menu
    //
    Character = BOXDRAW_DOWN_RIGHT;
    PrintCharAt (Start, Top, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = GEOMETRICSHAPE_UP_TRIANGLE;
      } else {
        Character = BOXDRAW_HORIZONTAL;
      }

      PrintChar (Character);
    }

    Character = BOXDRAW_DOWN_LEFT;
    PrintChar (Character);
    Character = BOXDRAW_VERTICAL;
    for (Index = Top + 1; Index < Bottom; Index++) {
      PrintCharAt (Start, Index, Character);
      PrintCharAt (End - 1, Index, Character);
    }

    //
    // Move to top Option
    //
    Link = GetFirstNode (&Question->OptionListHead);
    for (Index = 0; Index < TopOptionIndex; Index++) {
      Link = GetNextNode (&Question->OptionListHead, Link);
    }

    //
    // Display the One of options
    //
    Index2 = Top + 1;
    for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {
      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
      Link = GetNextNode (&Question->OptionListHead, Link);

      StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
      ASSERT (StringPtr != NULL);
      //
      // If the string occupies multiple lines, truncate it to fit in one line,
      // and append a "..." for indication.
      //
      if (StrLen (StringPtr) > (PopUpWidth - 1)) {
        TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));
        ASSERT ( TempStringPtr != NULL );
        CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));
        FreePool (StringPtr);
        StringPtr = TempStringPtr;
        StrCat (StringPtr, L"...");
      }

      if (Index == HighlightOptionIndex) {
          //
          // Highlight the selected one
          //
          CurrentOption = OneOfOption;

          gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
        } else {
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
        }

      Index2++;
      FreePool (StringPtr);
    }

    Character = BOXDRAW_UP_RIGHT;
    PrintCharAt (Start, Bottom, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = GEOMETRICSHAPE_DOWN_TRIANGLE;
      } else {
        Character = BOXDRAW_HORIZONTAL;
      }

      PrintChar (Character);
    }

    Character = BOXDRAW_UP_LEFT;
    PrintChar (Character);

    //
    // Get User selection
    //
    Key.UnicodeChar = CHAR_NULL;
    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {
      Key.ScanCode  = gDirection;
      gDirection    = 0;
      goto TheKey;
    }

    Status = WaitForKeyStroke (&Key);

TheKey:
    switch (Key.UnicodeChar) {
    case '+':
      if (OrderedList) {
        if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
          //
          // Highlight reaches the top of the popup window, scroll one menu item.
          //
          TopOptionIndex--;
          ShowDownArrow = TRUE;
        }

        if (TopOptionIndex == 0) {
          ShowUpArrow = FALSE;
        }

        if (HighlightOptionIndex > 0) {
          HighlightOptionIndex--;

          ASSERT (CurrentOption != NULL);
          SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link);
        }
      }
      break;

    case '-':
      //
      // If an ordered list op-code, we will allow for a popup of +/- keys
      // to create an ordered list of items
      //
      if (OrderedList) {
        if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
            (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {
          //
          // Highlight reaches the bottom of the popup window, scroll one menu item.
          //
          TopOptionIndex++;
          ShowUpArrow = TRUE;
        }

        if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
          ShowDownArrow = FALSE;
        }

        if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
          HighlightOptionIndex++;

          ASSERT (CurrentOption != NULL);
          SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink);
        }
      }
      break;

    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_UP:
      case SCAN_DOWN:
        if (Key.ScanCode == SCAN_UP) {
          if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
            //
            // Highlight reaches the top of the popup window, scroll one menu item.
            //
            TopOptionIndex--;
            ShowDownArrow = TRUE;
          }

          if (TopOptionIndex == 0) {
            ShowUpArrow = FALSE;
          }

          if (HighlightOptionIndex > 0) {
            HighlightOptionIndex--;
          }
        } else {
          if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
              (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {
            //
            // Highlight reaches the bottom of the popup window, scroll one menu item.
            //
            TopOptionIndex++;
            ShowUpArrow = TRUE;
          }

          if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
            ShowDownArrow = FALSE;
          }

          if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
            HighlightOptionIndex++;
          }
        }
        break;

      case SCAN_ESC:
        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

        //
        // Restore link list order for orderedlist
        //
        if (OrderedList) {
          HiiValue.Type = ValueType;
          HiiValue.Value.u64 = 0;
          for (Index = 0; Index < Question->MaxContainers; Index++) {
            HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
            if (HiiValue.Value.u64 == 0) {
              break;
            }

            OneOfOption = ValueToOption (Question, &HiiValue);
            if (OneOfOption == NULL) {
              return EFI_NOT_FOUND;
            }

            RemoveEntryList (&OneOfOption->Link);
            InsertTailList (&Question->OptionListHead, &OneOfOption->Link);
          }
        }

        FreePool (HiiValueArray);
        return EFI_DEVICE_ERROR;

      default:
        break;
      }

      break;

    case CHAR_CARRIAGE_RETURN:
      //
      // return the current selection
      //
      if (OrderedList) {
        Index = 0;
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

          SetArrayData (ValueArray, ValueType, Index, OneOfOption->Value.Value.u64);

          Index++;
          if (Index > Question->MaxContainers) {
            break;
          }

          Link = GetNextNode (&Question->OptionListHead, Link);
        }
      } else {
        ASSERT (CurrentOption != NULL);
        CopyMem (&Question->HiiValue, &CurrentOption->Value, sizeof (EFI_HII_VALUE));
      }

      gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
      FreePool (HiiValueArray);

      Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
      if (EFI_ERROR (Status)) {
        //
        // Input value is not valid, restore Question Value
        //
        GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
      } else {
        SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
        UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
      }

      return Status;

    default:
      break;
    }
  } while (TRUE);

}
Пример #20
0
NTSTATUS FdoPortStartIrp(
    IN PC0C_IO_PORT pIoPort,
    IN PIRP pIrp,
    IN UCHAR iQueue,
    IN PC0C_FDOPORT_START_ROUTINE pStartRoutine)
{
  NTSTATUS status;
  LIST_ENTRY queueToComplete;
  KIRQL oldIrql;
  PC0C_IRP_QUEUE pQueue;
  PC0C_IRP_STATE pState;

  InitializeListHead(&queueToComplete);
  pState = GetIrpState(pIrp);

  HALT_UNLESS(pState);

  pState->flags = 0;
  pState->iQueue = iQueue;

  pQueue = &pIoPort->irpQueues[iQueue];

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  #pragma warning(push, 3)
  IoSetCancelRoutine(pIrp, CancelRoutine);
  #pragma warning(pop)

  if (pIrp->Cancel) {
    status = NoPending(pIrp, STATUS_CANCELLED);
  } else {
    if (!pQueue->pCurrent) {
      status = StartIrp(pIoPort, pIrp, pState, pQueue, &queueToComplete, pStartRoutine);
    } else {
      PIO_STACK_LOCATION pIrpStack;
      PIO_STACK_LOCATION pCurrentStack;

      pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
      pCurrentStack = IoGetCurrentIrpStackLocation(pQueue->pCurrent);

      if (pIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
          pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_WAIT_ON_MASK)
      {
        status = NoPending(pIrp, STATUS_INVALID_PARAMETER);
      }
      else
      if (pIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
          pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR)
      {
        if (pCurrentStack->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
            pCurrentStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR)
        {
          status = NoPending(pIrp, STATUS_INVALID_PARAMETER);
        } else {
          PC0C_IRP_STATE pCurrentState;

          pCurrentState = GetIrpState(pQueue->pCurrent);

          HALT_UNLESS(pCurrentState);

          pCurrentState->flags &= ~C0C_IRP_FLAG_IS_CURRENT;
          InsertHeadList(&pQueue->queue, &pQueue->pCurrent->Tail.Overlay.ListEntry);
          pCurrentState->flags |= C0C_IRP_FLAG_IN_QUEUE;

          status = StartIrp(pIoPort, pIrp, pState, pQueue, &queueToComplete, pStartRoutine);
        }
      }
      else {
        InsertTailList(&pQueue->queue, &pIrp->Tail.Overlay.ListEntry);
        pState->flags |= C0C_IRP_FLAG_IN_QUEUE;

        if (pState->iQueue == C0C_QUEUE_WRITE) {
          pIoPort->amountInWriteQueue += GetWriteLength(pIrp);
        }

        if (pCurrentStack->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
            pCurrentStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_XOFF_COUNTER &&
            pQueue->pCurrent->IoStatus.Information)
        {
          if (pIrpStack->MajorFunction == IRP_MJ_FLUSH_BUFFERS) {
            RemoveEntryList(&pIrp->Tail.Overlay.ListEntry);
            pState->flags &= ~C0C_IRP_FLAG_IN_QUEUE;
            status = NoPending(pIrp, STATUS_SUCCESS);
          } else {
            PIRP pIrpXoffCounter = pQueue->pCurrent;

            ShiftQueue(pQueue);
            CompleteIrp(pIrpXoffCounter, STATUS_SERIAL_MORE_WRITES, &queueToComplete);

            status = StartIrp(pIoPort, pIrp, pState, pQueue, &queueToComplete, pStartRoutine);
          }
        } else {
          pIrp->IoStatus.Status = STATUS_PENDING;
          IoMarkIrpPending(pIrp);
          status = STATUS_PENDING;
        }
      }
    }
  }

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  FdoPortCompleteQueue(&queueToComplete);

  return status;
}
Пример #21
0
/***********************************************************************
 *           thread_init
 *
 * Setup the initial thread.
 *
 * NOTES: The first allocated TEB on NT is at 0x7ffde000.
 */
HANDLE thread_init(void)
{
    TEB *teb;
    void *addr;
    SIZE_T size, info_size;
    HANDLE exe_file = 0;
    LARGE_INTEGER now;
    struct ntdll_thread_data *thread_data;
    static struct debug_info debug_info;  /* debug info for initial thread */

    virtual_init();

    /* reserve space for shared user data */

    addr = (void *)0x7ffe0000;
    size = 0x10000;
    NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
    user_shared_data = addr;

    /* allocate and initialize the PEB */

    addr = NULL;
    size = sizeof(*peb);
    NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 1, &size,
                             MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE );
    peb = addr;

    peb->ProcessParameters  = &params;
    peb->TlsBitmap          = &tls_bitmap;
    peb->TlsExpansionBitmap = &tls_expansion_bitmap;
    peb->FlsBitmap          = &fls_bitmap;
    peb->LdrData            = &ldr;
    params.CurrentDirectory.DosPath.Buffer = current_dir;
    params.CurrentDirectory.DosPath.MaximumLength = sizeof(current_dir);
    params.wShowWindow = 1; /* SW_SHOWNORMAL */
    RtlInitializeBitMap( &tls_bitmap, peb->TlsBitmapBits, sizeof(peb->TlsBitmapBits) * 8 );
    RtlInitializeBitMap( &tls_expansion_bitmap, peb->TlsExpansionBitmapBits,
                         sizeof(peb->TlsExpansionBitmapBits) * 8 );
    RtlInitializeBitMap( &fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 );
    InitializeListHead( &peb->FlsListHead );
    InitializeListHead( &ldr.InLoadOrderModuleList );
    InitializeListHead( &ldr.InMemoryOrderModuleList );
    InitializeListHead( &ldr.InInitializationOrderModuleList );
    InitializeListHead( &tls_links );

    /* allocate and initialize the initial TEB */

    signal_alloc_thread( &teb );
    teb->Peb = peb;
    teb->Tib.StackBase = (void *)~0UL;
    teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
    teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);

    thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
    thread_data->request_fd = -1;
    thread_data->reply_fd   = -1;
    thread_data->wait_fd[0] = -1;
    thread_data->wait_fd[1] = -1;
    thread_data->debug_info = &debug_info;
    InsertHeadList( &tls_links, &teb->TlsLinks );

    signal_init_thread( teb );
    virtual_init_threading();

    debug_info.str_pos = debug_info.strings;
    debug_info.out_pos = debug_info.output;
    debug_init();

    /* setup the server connection */
    server_init_process();
    info_size = server_init_thread( peb );

    /* create the process heap */
    if (!(peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL )))
    {
        MESSAGE( "wine: failed to create the process heap\n" );
        exit(1);
    }

    /* allocate user parameters */
    if (info_size)
    {
        init_user_process_params( info_size, &exe_file );
    }
    else
    {
        /* This is wine specific: we have no parent (we're started from unix)
         * so, create a simple console with bare handles to unix stdio
         */
        wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE,  OBJ_INHERIT, &params.hStdInput );
        wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdOutput );
        wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdError );
    }

    /* initialize time values in user_shared_data */
    NtQuerySystemTime( &now );
    user_shared_data->SystemTime.LowPart = now.u.LowPart;
    user_shared_data->SystemTime.High1Time = user_shared_data->SystemTime.High2Time = now.u.HighPart;
    user_shared_data->u.TickCountQuad = (now.QuadPart - server_start_time) / 10000;
    user_shared_data->u.TickCount.High2Time = user_shared_data->u.TickCount.High1Time;
    user_shared_data->TickCountLowDeprecated = user_shared_data->u.TickCount.LowPart;
    user_shared_data->TickCountMultiplier = 1 << 24;

    fill_cpu_info();

    return exe_file;
}
Пример #22
0
/*
 * FUNCTION: Mount the filesystem
 */
static
NTSTATUS
VfatMount(
    PVFAT_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT DeviceObject = NULL;
    PDEVICE_EXTENSION DeviceExt = NULL;
    BOOLEAN RecognizedFS;
    NTSTATUS Status;
    PVFATFCB Fcb = NULL;
    PVFATFCB VolumeFcb = NULL;
    PVFATCCB Ccb = NULL;
    PDEVICE_OBJECT DeviceToMount;
    PVPB Vpb;
    UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$");
    UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\\$$Volume$$");
    ULONG HashTableSize;
    ULONG eocMark;
    FATINFO FatInfo;

    DPRINT("VfatMount(IrpContext %p)\n", IrpContext);

    ASSERT(IrpContext);

    if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject)
    {
        Status = STATUS_INVALID_DEVICE_REQUEST;
        goto ByeBye;
    }

    DeviceToMount = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
    Vpb = IrpContext->Stack->Parameters.MountVolume.Vpb;

    Status = VfatHasFileSystem(DeviceToMount, &RecognizedFS, &FatInfo);
    if (!NT_SUCCESS(Status))
    {
        goto ByeBye;
    }

    if (RecognizedFS == FALSE)
    {
        DPRINT("VFAT: Unrecognized Volume\n");
        Status = STATUS_UNRECOGNIZED_VOLUME;
        goto ByeBye;
    }

    /* Use prime numbers for the table size */
    if (FatInfo.FatType == FAT12)
    {
        HashTableSize = 4099; // 4096 = 4 * 1024
    }
    else if (FatInfo.FatType == FAT16 ||
             FatInfo.FatType == FATX16)
    {
        HashTableSize = 16411; // 16384 = 16 * 1024
    }
    else
    {
        HashTableSize = 65537; // 65536 = 64 * 1024;
    }
    HashTableSize = FCB_HASH_TABLE_SIZE;
    DPRINT("VFAT: Recognized volume\n");
    Status = IoCreateDevice(VfatGlobalData->DriverObject,
                            ROUND_UP(sizeof (DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize,
                            NULL,
                            FILE_DEVICE_DISK_FILE_SYSTEM,
                            DeviceToMount->Characteristics,
                            FALSE,
                            &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        goto ByeBye;
    }

    DeviceExt = DeviceObject->DeviceExtension;
    RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize);
    DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));
    DeviceExt->HashTableSize = HashTableSize;
    DeviceExt->VolumeDevice = DeviceObject;

    /* use same vpb as device disk */
    DeviceObject->Vpb = Vpb;
    DeviceToMount->Vpb = Vpb;

    Status = VfatMountDevice(DeviceExt, DeviceToMount);
    if (!NT_SUCCESS(Status))
    {
        /* FIXME: delete device object */
        goto ByeBye;
    }

    DPRINT("BytesPerSector:     %u\n", DeviceExt->FatInfo.BytesPerSector);
    DPRINT("SectorsPerCluster:  %u\n", DeviceExt->FatInfo.SectorsPerCluster);
    DPRINT("FATCount:           %u\n", DeviceExt->FatInfo.FATCount);
    DPRINT("FATSectors:         %u\n", DeviceExt->FatInfo.FATSectors);
    DPRINT("RootStart:          %u\n", DeviceExt->FatInfo.rootStart);
    DPRINT("DataStart:          %u\n", DeviceExt->FatInfo.dataStart);
    if (DeviceExt->FatInfo.FatType == FAT32)
    {
        DPRINT("RootCluster:        %u\n", DeviceExt->FatInfo.RootCluster);
    }

    switch (DeviceExt->FatInfo.FatType)
    {
        case FAT12:
            DeviceExt->GetNextCluster = FAT12GetNextCluster;
            DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
            DeviceExt->WriteCluster = FAT12WriteCluster;
            DeviceExt->CleanShutBitMask = 0;
            break;

        case FAT16:
        case FATX16:
            DeviceExt->GetNextCluster = FAT16GetNextCluster;
            DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
            DeviceExt->WriteCluster = FAT16WriteCluster;
            DeviceExt->CleanShutBitMask = 0x8000;
            break;

        case FAT32:
        case FATX32:
            DeviceExt->GetNextCluster = FAT32GetNextCluster;
            DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
            DeviceExt->WriteCluster = FAT32WriteCluster;
            DeviceExt->CleanShutBitMask = 0x80000000;
            break;
    }

    if (DeviceExt->FatInfo.FatType == FATX16 ||
        DeviceExt->FatInfo.FatType == FATX32)
    {
        DeviceExt->Flags |= VCB_IS_FATX;
        DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;
        DeviceExt->BaseDateYear = 2000;
    }
    else
    {
        DeviceExt->GetNextDirEntry = FATGetNextDirEntry;
        DeviceExt->BaseDateYear = 1980;
    }

    DeviceExt->StorageDevice = DeviceToMount;
    DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
    DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
    DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
    DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    DPRINT("FsDeviceObject %p\n", DeviceObject);

    /* Initialize this resource early ... it's used in VfatCleanup */
    ExInitializeResourceLite(&DeviceExt->DirResource);

    DeviceExt->IoVPB = DeviceObject->Vpb;
    DeviceExt->SpareVPB = ExAllocatePoolWithTag(NonPagedPool, sizeof(VPB), TAG_VFAT);
    if (DeviceExt->SpareVPB == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto ByeBye;
    }

    DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
    Fcb = vfatNewFCB(DeviceExt, &NameU);
    if (Fcb == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto ByeBye;
    }

    Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
    if (Ccb == NULL)
    {
        Status =  STATUS_INSUFFICIENT_RESOURCES;
        goto ByeBye;
    }

    RtlZeroMemory(Ccb, sizeof (VFATCCB));
    DeviceExt->FATFileObject->FsContext = Fcb;
    DeviceExt->FATFileObject->FsContext2 = Ccb;
    DeviceExt->FATFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
    DeviceExt->FATFileObject->PrivateCacheMap = NULL;
    DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
    Fcb->FileObject = DeviceExt->FATFileObject;

    Fcb->Flags |= FCB_IS_FAT;

    Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
    Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
    Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;

    _SEH2_TRY
    {
        CcInitializeCacheMap(DeviceExt->FATFileObject,
                             (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
                             TRUE,
                             &VfatGlobalData->CacheMgrCallbacks,
                             Fcb);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
        goto ByeBye;
    }
    _SEH2_END;

    DeviceExt->LastAvailableCluster = 2;
    ExInitializeResourceLite(&DeviceExt->FatResource);

    InitializeListHead(&DeviceExt->FcbListHead);

    VolumeFcb = vfatNewFCB(DeviceExt, &VolumeNameU);
    if (VolumeFcb == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto ByeBye;
    }

    VolumeFcb->Flags = FCB_IS_VOLUME;
    VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * DeviceExt->FatInfo.BytesPerSector;
    VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;
    VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;
    DeviceExt->VolumeFcb = VolumeFcb;

    ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
    InsertHeadList(&VfatGlobalData->VolumeListHead, &DeviceExt->VolumeListEntry);
    ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);

    /* read serial number */
    DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;

    /* read volume label */
    ReadVolumeLabel(DeviceExt,  DeviceObject->Vpb);

    /* read clean shutdown bit status */
    Status = GetNextCluster(DeviceExt, 1, &eocMark);
    if (NT_SUCCESS(Status))
    {
        if (eocMark & DeviceExt->CleanShutBitMask)
        {
            /* unset clean shutdown bit */
            eocMark &= ~DeviceExt->CleanShutBitMask;
            WriteCluster(DeviceExt, 1, eocMark);
            VolumeFcb->Flags |= VCB_CLEAR_DIRTY;
        }
    }

    VolumeFcb->Flags |= VCB_IS_DIRTY;

    FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT);
    FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
    InitializeListHead(&DeviceExt->NotifyList);

    DPRINT("Mount success\n");

    Status = STATUS_SUCCESS;

ByeBye:
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup */
        if (DeviceExt && DeviceExt->FATFileObject)
            ObDereferenceObject (DeviceExt->FATFileObject);
        if (DeviceExt && DeviceExt->SpareVPB)
            ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VFAT);
        if (Fcb)
            vfatDestroyFCB(Fcb);
        if (Ccb)
            vfatDestroyCCB(Ccb);
        if (DeviceObject)
            IoDeleteDevice(DeviceObject);
    }

    return Status;
}
Пример #23
0
static NTSTATUS NTAPI SendComplete
( PDEVICE_OBJECT DeviceObject,
  PIRP Irp,
  PVOID Context ) {
    NTSTATUS Status = Irp->IoStatus.Status;
    PAFD_FCB FCB = (PAFD_FCB)Context;
    PLIST_ENTRY NextIrpEntry;
    PIRP NextIrp = NULL;
    PIO_STACK_LOCATION NextIrpSp;
    PAFD_SEND_INFO SendReq = NULL;
    PAFD_MAPBUF Map;
    UINT TotalBytesCopied = 0, TotalBytesProcessed = 0, SpaceAvail, i;
    UINT SendLength, BytesCopied;
    BOOLEAN HaltSendQueue;

    UNREFERENCED_PARAMETER(DeviceObject);

    /*
     * The Irp parameter passed in is the IRP of the stream between AFD and
     * TDI driver. It's not very usefull to us. We need the IRPs of the stream
     * between usermode and AFD. Those are chained from
     * FCB->PendingIrpList[FUNCTION_SEND] and you'll see them in the code
     * below as "NextIrp" ('cause they are the next usermode IRP to be
     * processed).
     */

    AFD_DbgPrint(MID_TRACE,("Called, status %x, %u bytes used\n",
                            Irp->IoStatus.Status,
                            Irp->IoStatus.Information));

    if( !SocketAcquireStateLock( FCB ) )
        return STATUS_FILE_CLOSED;

    ASSERT(FCB->SendIrp.InFlightRequest == Irp);
    FCB->SendIrp.InFlightRequest = NULL;
    /* Request is not in flight any longer */

    if( FCB->State == SOCKET_STATE_CLOSED ) {
        /* Cleanup our IRP queue because the FCB is being destroyed */
        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
            NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
            NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
            NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
            SendReq = GetLockedData(NextIrp, NextIrpSp);
            NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
            NextIrp->IoStatus.Information = 0;
            UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
            if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
            (void)IoSetCancelRoutine(NextIrp, NULL);
            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
        }

        RetryDisconnectCompletion(FCB);

        SocketStateUnlock( FCB );
        return STATUS_FILE_CLOSED;
    }

    if( !NT_SUCCESS(Status) ) {
        /* Complete all following send IRPs with error */

        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
            NextIrpEntry =
                RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
            NextIrp =
                CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
            NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
            SendReq = GetLockedData(NextIrp, NextIrpSp);

            UnlockBuffers( SendReq->BufferArray,
                           SendReq->BufferCount,
                           FALSE );

            NextIrp->IoStatus.Status = Status;
            NextIrp->IoStatus.Information = 0;

            if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
            (void)IoSetCancelRoutine(NextIrp, NULL);
            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
        }

        RetryDisconnectCompletion(FCB);

        SocketStateUnlock( FCB );

        return STATUS_SUCCESS;
    }

    RtlMoveMemory( FCB->Send.Window,
                   FCB->Send.Window + Irp->IoStatus.Information,
                   FCB->Send.BytesUsed - Irp->IoStatus.Information );

    TotalBytesProcessed = 0;
    SendLength = Irp->IoStatus.Information;
    HaltSendQueue = FALSE;
    while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && SendLength > 0) {
        NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
        NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
        NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
        SendReq = GetLockedData(NextIrp, NextIrpSp);
        Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);

        TotalBytesCopied = (ULONG_PTR)NextIrp->Tail.Overlay.DriverContext[3];
        ASSERT(TotalBytesCopied != 0);

        /* If we didn't get enough, keep waiting */
        if (TotalBytesCopied > SendLength)
        {
            /* Update the bytes left to copy */
            TotalBytesCopied -= SendLength;
            NextIrp->Tail.Overlay.DriverContext[3] = (PVOID)TotalBytesCopied;

            /* Update the state variables */
            FCB->Send.BytesUsed -= SendLength;
            TotalBytesProcessed += SendLength;
            SendLength = 0;

            /* Pend the IRP */
            InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND],
                           &NextIrp->Tail.Overlay.ListEntry);
            HaltSendQueue = TRUE;
            break;
        }

        ASSERT(NextIrp->IoStatus.Information != 0);

        NextIrp->IoStatus.Status = Irp->IoStatus.Status;

        FCB->Send.BytesUsed -= TotalBytesCopied;
        TotalBytesProcessed += TotalBytesCopied;
        SendLength -= TotalBytesCopied;

        (void)IoSetCancelRoutine(NextIrp, NULL);

        UnlockBuffers( SendReq->BufferArray,
                       SendReq->BufferCount,
                       FALSE );

        if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp);

        IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT);
    }

    ASSERT(SendLength == 0);

    if ( !HaltSendQueue && !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
        NextIrpEntry = FCB->PendingIrpList[FUNCTION_SEND].Flink;
        NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
        NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
        SendReq = GetLockedData(NextIrp, NextIrpSp);
        Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);

        AFD_DbgPrint(MID_TRACE,("SendReq @ %p\n", SendReq));

        SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
        TotalBytesCopied = 0;

        /* Count the total transfer size */
        SendLength = 0;
        for (i = 0; i < SendReq->BufferCount; i++)
        {
            SendLength += SendReq->BufferArray[i].len;
        }

        /* Make sure we've got the space */
        if (SendLength > SpaceAvail)
        {
            /* Blocking sockets have to wait here */
            if (SendLength <= FCB->Send.Size && !((SendReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
            {
                FCB->PollState &= ~AFD_EVENT_SEND;

                NextIrp = NULL;
            }

            /* Check if we can send anything */
            if (SpaceAvail == 0)
            {
                FCB->PollState &= ~AFD_EVENT_SEND;

                /* We should never be non-overlapped and get to this point */
                ASSERT(SendReq->AfdFlags & AFD_OVERLAPPED);

                NextIrp = NULL;
            }
        }

        if (NextIrp != NULL)
        {
            for( i = 0; i < SendReq->BufferCount; i++ ) {
                BytesCopied = MIN(SendReq->BufferArray[i].len, SpaceAvail);

                Map[i].BufferAddress =
                    MmMapLockedPages( Map[i].Mdl, KernelMode );

                RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
                               Map[i].BufferAddress,
                               BytesCopied );

                MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );

                TotalBytesCopied += BytesCopied;
                SpaceAvail -= BytesCopied;
                FCB->Send.BytesUsed += BytesCopied;
            }

            NextIrp->IoStatus.Information = TotalBytesCopied;
            NextIrp->Tail.Overlay.DriverContext[3] = (PVOID)NextIrp->IoStatus.Information;
        }
    }

    if (FCB->Send.Size - FCB->Send.BytesUsed != 0 && !FCB->SendClosed &&
            IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]))
    {
        FCB->PollState |= AFD_EVENT_SEND;
        FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
        PollReeval( FCB->DeviceExt, FCB->FileObject );
    }
    else
    {
        FCB->PollState &= ~AFD_EVENT_SEND;
    }


    /* Some data is still waiting */
    if( FCB->Send.BytesUsed )
    {
        Status = TdiSend( &FCB->SendIrp.InFlightRequest,
                          FCB->Connection.Object,
                          0,
                          FCB->Send.Window,
                          FCB->Send.BytesUsed,
                          SendComplete,
                          FCB );
    }
    else
    {
        /* Nothing is waiting so try to complete a pending disconnect */
        RetryDisconnectCompletion(FCB);
    }

    SocketStateUnlock( FCB );

    return STATUS_SUCCESS;
}
Пример #24
0
NTSTATUS
CcRosTrimCache (
    ULONG Target,
    ULONG Priority,
    PULONG NrFreed)
/*
 * FUNCTION: Try to free some memory from the file cache.
 * ARGUMENTS:
 *       Target - The number of pages to be freed.
 *       Priority - The priority of free (currently unused).
 *       NrFreed - Points to a variable where the number of pages
 *                 actually freed is returned.
 */
{
    PLIST_ENTRY current_entry;
    PROS_VACB current;
    ULONG PagesFreed;
    KIRQL oldIrql;
    LIST_ENTRY FreeList;
    PFN_NUMBER Page;
    ULONG i;
    BOOLEAN FlushedPages = FALSE;

    DPRINT("CcRosTrimCache(Target %lu)\n", Target);

    InitializeListHead(&FreeList);

    *NrFreed = 0;

retry:
    KeAcquireGuardedMutex(&ViewLock);

    current_entry = VacbLruListHead.Flink;
    while (current_entry != &VacbLruListHead)
    {
        current = CONTAINING_RECORD(current_entry,
                                    ROS_VACB,
                                    VacbLruListEntry);
        current_entry = current_entry->Flink;

        KeAcquireSpinLock(&current->SharedCacheMap->CacheMapLock, &oldIrql);

        /* Reference the VACB */
        CcRosVacbIncRefCount(current);

        /* Check if it's mapped and not dirty */
        if (current->MappedCount > 0 && !current->Dirty)
        {
            /* We have to break these locks because Cc sucks */
            KeReleaseSpinLock(&current->SharedCacheMap->CacheMapLock, oldIrql);
            KeReleaseGuardedMutex(&ViewLock);

            /* Page out the VACB */
            for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++)
            {
                Page = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)current->BaseAddress + (i * PAGE_SIZE)).QuadPart >> PAGE_SHIFT);

                MmPageOutPhysicalAddress(Page);
            }

            /* Reacquire the locks */
            KeAcquireGuardedMutex(&ViewLock);
            KeAcquireSpinLock(&current->SharedCacheMap->CacheMapLock, &oldIrql);
        }

        /* Dereference the VACB */
        CcRosVacbDecRefCount(current);

        /* Check if we can free this entry now */
        if (current->ReferenceCount == 0)
        {
            ASSERT(!current->Dirty);
            ASSERT(!current->MappedCount);

            RemoveEntryList(&current->CacheMapVacbListEntry);
            RemoveEntryList(&current->VacbLruListEntry);
            InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);

            /* Calculate how many pages we freed for Mm */
            PagesFreed = min(VACB_MAPPING_GRANULARITY / PAGE_SIZE, Target);
            Target -= PagesFreed;
            (*NrFreed) += PagesFreed;
        }

        KeReleaseSpinLock(&current->SharedCacheMap->CacheMapLock, oldIrql);
    }
Пример #25
0
NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHAR RecvBuffer, UINT RecvLen, UINT *Received)
{
    PQUEUE_ENTRY qp;
    struct pbuf* p;
    NTSTATUS Status;
    UINT ReadLength, PayloadLength, Offset, Copied;
    KIRQL OldIrql;

    (*Received) = 0;

    LockObject(Connection, &OldIrql);

    if (!IsListEmpty(&Connection->PacketQueue))
    {
        while ((qp = LibTCPDequeuePacket(Connection)) != NULL)
        {
            p = qp->p;

            /* Calculate the payload length first */
            PayloadLength = p->tot_len;
            PayloadLength -= qp->Offset;
            Offset = qp->Offset;

            /* Check if we're reading the whole buffer */
            ReadLength = MIN(PayloadLength, RecvLen);
            ASSERT(ReadLength != 0);
            if (ReadLength != PayloadLength)
            {
                /* Save this one for later */
                qp->Offset += ReadLength;
                InsertHeadList(&Connection->PacketQueue, &qp->ListEntry);
                qp = NULL;
            }

            UnlockObject(Connection, OldIrql);

            Copied = pbuf_copy_partial(p, RecvBuffer, ReadLength, Offset);
            ASSERT(Copied == ReadLength);

            LockObject(Connection, &OldIrql);

            /* Update trackers */
            RecvLen -= ReadLength;
            RecvBuffer += ReadLength;
            (*Received) += ReadLength;

            if (qp != NULL)
            {
                /* Use this special pbuf free callback function because we're outside tcpip thread */
                pbuf_free_callback(qp->p);

                ExFreeToNPagedLookasideList(&QueueEntryLookasideList, qp);
            }
            else
            {
                /* If we get here, it means we've filled the buffer */
                ASSERT(RecvLen == 0);
            }

            ASSERT((*Received) != 0);
            Status = STATUS_SUCCESS;

            if (!RecvLen)
                break;
        }
    }
    else
    {
        if (Connection->ReceiveShutdown)
            Status = Connection->ReceiveShutdownStatus;
        else
            Status = STATUS_PENDING;
    }

    UnlockObject(Connection, OldIrql);

    return Status;
}
Пример #26
0
ULONG64
NTAPI
HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                        IN ULONG64 MaxAddress,
                        IN PFN_NUMBER PageCount,
                        IN BOOLEAN Aligned)
{
    ULONG UsedDescriptors;
    ULONG64 PhysicalAddress;
    PFN_NUMBER MaxPage, BasePage, Alignment;
    PLIST_ENTRY NextEntry;
    PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock;

    /* Highest page we'll go */
    MaxPage = MaxAddress >> PAGE_SHIFT;

    /* We need at least two blocks */
    if ((HalpUsedAllocDescriptors + 2) > 64) return 0;

    /* Remember how many we have now */
    UsedDescriptors = HalpUsedAllocDescriptors;

    /* Loop the loader block memory descriptors */
    NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
    while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
    {
        /* Get the block */
        MdBlock = CONTAINING_RECORD(NextEntry,
                                    MEMORY_ALLOCATION_DESCRIPTOR,
                                    ListEntry);

        /* No alignment by default */
        Alignment = 0;

        /* Unless requested, in which case we use a 64KB block alignment */
        if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage;

        /* Search for free memory */
        if ((MdBlock->MemoryType == LoaderFree) ||
            (MdBlock->MemoryType == LoaderFirmwareTemporary))
        {
            /* Make sure the page is within bounds, including alignment */
            BasePage = MdBlock->BasePage;
            if ((BasePage) &&
                (MdBlock->PageCount >= PageCount + Alignment) &&
                (BasePage + PageCount + Alignment < MaxPage))
            {
                /* We found an address */
                PhysicalAddress = ((ULONG64)BasePage + Alignment) << PAGE_SHIFT;
                break;
            }
        }

        /* Keep trying */
        NextEntry = NextEntry->Flink;
    }

    /* If we didn't find anything, get out of here */
    if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0;

    /* Okay, now get a descriptor */
    NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors];
    NewBlock->PageCount = (ULONG)PageCount;
    NewBlock->BasePage = MdBlock->BasePage + Alignment;
    NewBlock->MemoryType = LoaderHALCachedMemory;

    /* Update count */
    UsedDescriptors++;
    HalpUsedAllocDescriptors = UsedDescriptors;

    /* Check if we had any alignment */
    if (Alignment)
    {
        /* Check if we had leftovers */
        if (MdBlock->PageCount > (PageCount + Alignment))
        {
            /* Get the next descriptor */
            FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors];
            FreeBlock->PageCount = MdBlock->PageCount - Alignment - (ULONG)PageCount;
            FreeBlock->BasePage = MdBlock->BasePage + Alignment + (ULONG)PageCount;

            /* One more */
            HalpUsedAllocDescriptors++;

            /* Insert it into the list */
            InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry);
        }

        /* Trim the original block to the alignment only */
        MdBlock->PageCount = Alignment;

        /* Insert the descriptor after the original one */
        InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry);
    }
    else
    {
        /* Consume memory from this block */
        MdBlock->BasePage += (ULONG)PageCount;
        MdBlock->PageCount -= (ULONG)PageCount;

        /* Insert the descriptor before the original one */
        InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry);

        /* Remove the entry if the whole block was allocated */
        if (MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry);
    }

    /* Return the address */
    return PhysicalAddress;
}
Пример #27
0
DWORD
WSAAPI
WsNqLookupServiceNext(IN PNSQUERY NsQuery,
                      IN DWORD ControlFlags,
                      OUT PDWORD BufferLength,
                      OUT LPWSAQUERYSETW Results)
{
    PNSQUERY_PROVIDER Provider, NextProvider;
    INT ErrorCode = SOCKET_ERROR, OldErrorCode;
    PLIST_ENTRY Entry;

    /* Make sure we're not shutting down */
    if (!NsQuery->ShuttingDown)
    {
        /* Acquire query lock */
        WsNqLock();

        /* Check if we already have an active provider */
        NextProvider = NsQuery->ActiveProvider;
        if (!NextProvider)
        {
            /* Make sure we have a current provider */
            if (!NsQuery->CurrentProvider)
            {
                /* We don't; fail */
                WsNqUnlock();
                SetLastError(WSA_E_NO_MORE);
                return SOCKET_ERROR;
            }

            /* Get the first provider on the list and start looping */
            Entry = NsQuery->ProviderList.Blink;
            NextProvider = CONTAINING_RECORD(Entry, NSQUERY_PROVIDER, QueryLink);
            while (NextProvider)
            {
                /* Check if this is a new-style provider */
                if (NextProvider->Provider->Service.NSPIoctl)
                {
                    /* Remove it and re-add it on top */
                    RemoveEntryList(&NextProvider->QueryLink);
                    InsertHeadList(&NsQuery->ProviderList, &NextProvider->QueryLink);

                    /* Set it as the active provider and exit the loop */
                    NsQuery->ActiveProvider = NextProvider;
                    break;
                }

                /* Get the previous provider */
                NextProvider = WsNqPreviousProvider(NsQuery, NextProvider);
            }
        }

        /* Release the lock */
        WsNqUnlock();

        /* Check if we have an active provider now */
        if (NextProvider)
        {
            /* Start loop */
            do
            {
                /* Call its routine */
                ErrorCode = WsNqProvLookupServiceNext(NextProvider,
                                                      ControlFlags,
                                                      BufferLength,
                                                      Results);
                /* Check for error or shutdown */
                if ((ErrorCode == ERROR_SUCCESS) ||
                    (GetLastError() == WSAEFAULT) || (NsQuery->ShuttingDown))
                {
                    /* Get out */
                    break;
                }

                /* Acquire Query Lock */
                WsNqLock();

                /* Save the current active provider */
                Provider = NsQuery->ActiveProvider;
                
                /* Check if one exists */
                if (Provider)
                {
                    /* Get the next one */
                    NextProvider = WsNqNextProvider(NsQuery,
                                                    NsQuery->ActiveProvider);

                    /* Was the old provider our active? */
                    if (Provider == NsQuery->ActiveProvider)
                    {
                        /* Change our active provider to the new one */
                        NsQuery->ActiveProvider = NextProvider;
                    }
                }
                else
                {
                    /* No next provider */
                    NextProvider = NULL;
                }

                /* Check if we failed and if we can try again */
                if (!(NextProvider) &&
                    (ErrorCode == SOCKET_ERROR) &&
                    (NsQuery->TryAgain))
                {
                    /* Save the error code so RAS doesn't overwrite it */
                    OldErrorCode = GetLastError();

                    /* Make sure we won't try for a 3rd time */
                    NsQuery->TryAgain = FALSE;

                    /* Call the helper to auto-dial */
                    if (WSAttemptAutodialName(NsQuery->QuerySet))
                    {
                        /* It suceeded, so we'll delete the current state. */
                        while (!IsListEmpty(&NsQuery->ProviderList))
                        {
                            /* Remove the entry and get its provider */
                            Entry = RemoveHeadList(&NsQuery->ProviderList);
                            Provider = CONTAINING_RECORD(Entry,
                                                         NSQUERY_PROVIDER,
                                                         QueryLink);

                            /* Reset it */
                            WsNqProvLookupServiceEnd(Provider);
                            WsNqProvDelete(Provider);
                        }                  

                        /* Start a new query */
                        if (!WsNqLookupServiceBegin(NsQuery,
                                                    NsQuery->QuerySet,
                                                    NsQuery->ControlFlags,
                                                    NsQuery->Catalog))
                        {
                            /* New query succeeded, set active provider now */
                            NsQuery->ActiveProvider = 
                                WsNqNextProvider(NsQuery,
                                                 NsQuery->ActiveProvider);
                        }
                    }
                    else
                    {
                        /* Reset the error code */
                        SetLastError(OldErrorCode);
                    }
                }

                /* Release lock */
                WsNqUnlock();

                /* Keep looping as long as there is a provider */
            } while (NextProvider);   
        }
    }
    else
    {
        /* We are shuting down; fail */
        SetLastError(WSAECANCELLED);
    }

    /* Return */
    return ErrorCode;
}
Пример #28
0
/**
 * This is a debug only function that performs memory management operations for us.
 * Memory allocated using this function is tracked, flagged when leaked, and caught for
 * overflows and underflows.
 * \warning Do not use this function directly. Using MP_ALLOCATE_MEMORY ensures that
 * this function gets called for debug version of the driver. Retail builds will use Ndis API
 * for allocation of memory
 * 
 * \param Size            The size in bytes of memory to allocate
 * \param FileName  The full path of file where this function is invoked from
 * \param LineNumber The line number in the file where this method was called from
 * \param Flags           Flags for special memory insturctions. Currently unused.
 * \return Pointer to the allocated memory or NULL in case of a failure
 * \sa MpFreeMemory, MP_ALLOCATE_MEMORY, MP_FREE_MEMORY, NdisAllocateMemoryWithTagPriority, MpFreeAllocatedBlocks
 */
PVOID 
MpAllocateMemory (
    NDIS_HANDLE           AllocateHandle,
    ULONG                 Size,
    ULONG                 Tag,
    EX_POOL_PRIORITY      Priority,
    __nullterminated PCHAR FileName,
    ULONG                 LineNumber,
    ULONG                 Flags
    )
{
    PVOID   memory = NULL;

    //
    // If the memory manager has not been initialized, do so now
    //
    if (!GlobalMemoryManagerInitialized)
    {
        //
        // NOTE: If two thread allocate the very first allocation simultaneously
        // it could cause double initialization of the memory manager. This is a
        // highly unlikely scenario and will occur in debug versions only.
        //
        NdisAllocateSpinLock(&GlobalMemoryLock);
        InitializeListHead(&GlobalMemoryList);
        GlobalMemoryManagerInitialized = TRUE;
    }

    //
    // Allocate the required memory chunk plus header and trailer bytes
    //
    memory = NdisAllocateMemoryWithTagPriority(
        AllocateHandle,
        Size + sizeof(MP_MEMORY_BLOCK) + sizeof(ULONG),
        Tag,
        Priority
        );

    if (memory != NULL)
    {
        //
        // Memory allocation succeeded. Add information about the allocated
        // block in the list that tracks all allocations.
        //
        PMP_MEMORY_BLOCK  memoryBlockHeader;

        // Fill in the memory header and trailer
        memoryBlockHeader = (PMP_MEMORY_BLOCK) memory;
        memoryBlockHeader->File = FileName;
        memoryBlockHeader->Line = LineNumber;
        memoryBlockHeader->Length = Size;
        memoryBlockHeader->Flags = Flags;
        memoryBlockHeader->HeaderPattern = MP_HEADER_PATTERN;
        *((PULONG) (((PUCHAR)(memory))+Size + sizeof(MP_MEMORY_BLOCK))) = MP_TRAILER_PATTERN;

        // Jump ahead by memory header so pointer returned to caller points at the right place
        memory = ((PUCHAR)memory) + sizeof (MP_MEMORY_BLOCK);

        // Store a reference to this block in the list
        NdisAcquireSpinLock (&GlobalMemoryLock);
        InsertHeadList (&GlobalMemoryList, &memoryBlockHeader->ListEntry);
        NdisReleaseSpinLock (&GlobalMemoryLock);
    }

    return memory;
}
NTSTATUS
RosKmAdapter::Start(
    IN_PDXGK_START_INFO     DxgkStartInfo,
    IN_PDXGKRNL_INTERFACE   DxgkInterface,
    OUT_PULONG              NumberOfVideoPresentSources,
    OUT_PULONG              NumberOfChildren)
{
    m_DxgkStartInfo = *DxgkStartInfo;
    m_DxgkInterface = *DxgkInterface;

    //
    // Render only device has no VidPn source and target
    //
    *NumberOfVideoPresentSources = 0;
    *NumberOfChildren = 0;

    //
    // Sample for 1.3 model currently
    //
    m_WDDMVersion = DXGKDDI_WDDMv1_3;

    m_NumNodes = C_ROSD_GPU_ENGINE_COUNT;

    //
    // Initialize worker
    //

    KeInitializeEvent(&m_workerThreadEvent, SynchronizationEvent, FALSE);

    m_workerExit = false;

    OBJECT_ATTRIBUTES   ObjectAttributes;
    HANDLE              hWorkerThread;

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

    NTSTATUS status = PsCreateSystemThread(
        &hWorkerThread,
        THREAD_ALL_ACCESS,
        &ObjectAttributes,
        NULL,
        NULL,
        (PKSTART_ROUTINE) RosKmAdapter::WorkerThread,
        this);

    if (status != STATUS_SUCCESS)
    {
        return status;
    }

    status = ObReferenceObjectByHandle(
        hWorkerThread,
        THREAD_ALL_ACCESS,
        *PsThreadType,
        KernelMode,
        (PVOID *)&m_pWorkerThread,
        NULL);

    ZwClose(hWorkerThread);

    if (status != STATUS_SUCCESS)
    {
        return status;
    }

    status = m_DxgkInterface.DxgkCbGetDeviceInformation(
        m_DxgkInterface.DeviceHandle,
        &m_deviceInfo);
    NT_ASSERT(status == STATUS_SUCCESS);

    //
    // Query APCI device ID
    //
    {
        NTSTATUS acpiStatus;

        RosKmAcpiReader acpiReader(this, DISPLAY_ADAPTER_HW_ID);
        acpiStatus = acpiReader.Read(ACPI_METHOD_HARDWARE_ID);
        if (NT_SUCCESS(acpiStatus) && (acpiReader.GetOutputArgumentCount() == 1))
        {
            RosKmAcpiArgumentParser acpiParser(&acpiReader, NULL);
            char *pDeviceId;
            ULONG DeviceIdLength;
            acpiStatus = acpiParser.GetAnsiString(&pDeviceId, &DeviceIdLength);
            if (NT_SUCCESS(acpiStatus) && DeviceIdLength)
            {
                m_deviceIdLength = min(DeviceIdLength, sizeof(m_deviceId));
                RtlCopyMemory(&m_deviceId[0], pDeviceId, m_deviceIdLength);
            }
        }
    }

    //
    // Initialize power component data.
    //
    InitializePowerComponentInfo();

    //
    // Initialize apperture state
    //

    memset(m_aperturePageTable, 0, sizeof(m_aperturePageTable));

    //
    // Intialize DMA buffer queue and lock
    //

    InitializeListHead(&m_dmaBufSubmissionFree);
    for (UINT i = 0; i < m_maxDmaBufQueueLength; i++)
    {
        InsertHeadList(&m_dmaBufSubmissionFree, &m_dmaBufSubssions[i].m_QueueEntry);
    }

    InitializeListHead(&m_dmaBufQueue);
    KeInitializeSpinLock(&m_dmaBufQueueLock);

    //
    // Initialize HW DMA buffer compeletion DPC and event
    //

    KeInitializeEvent(&m_hwDmaBufCompletionEvent, SynchronizationEvent, FALSE);
    KeInitializeDpc(&m_hwDmaBufCompletionDpc, HwDmaBufCompletionDpcRoutine, this);

    return STATUS_SUCCESS;
}
Пример #30
0
HDC FASTCALL
UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
{
   PWND Parent;
   ULONG DcxFlags;
   DCE* Dce = NULL;
   BOOL UpdateClipOrigin = FALSE;
   BOOL bUpdateVisRgn = TRUE;
   HDC hDC = NULL;
   PPROCESSINFO ppi;
   PLIST_ENTRY ListEntry;

   if (NULL == Wnd)
   {
      Flags &= ~DCX_USESTYLE;
      Flags |= DCX_CACHE;
   }

   if (Flags & DCX_PARENTCLIP) Flags |= DCX_CACHE;

   // When GetDC is called with hWnd nz, DCX_CACHE & _WINDOW are clear w _USESTYLE set.
   if (Flags & DCX_USESTYLE)
   {
      Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
      if (!(Flags & DCX_WINDOW)) // Not window rectangle
      {
         if (Wnd->pcls->style & CS_PARENTDC)
         {
            Flags |= DCX_PARENTCLIP;
         }

         if (!(Flags & DCX_CACHE) && // Not on the cheap wine list.
             !(Wnd->pcls->style & CS_OWNDC) )
         {
            if (!(Wnd->pcls->style & CS_CLASSDC))
            // The window is not POWNED or has any CLASS, so we are looking for cheap wine.
               Flags |= DCX_CACHE;
            else
            {
               if (Wnd->pcls->pdce) hDC = ((PDCE)Wnd->pcls->pdce)->hDC;
               TRACE("We have CLASS!!\n");
            }
         }

         if (Wnd->style & WS_CLIPSIBLINGS)
         {
            Flags |= DCX_CLIPSIBLINGS;
         }

         if (Wnd->style & WS_CLIPCHILDREN &&
             !(Wnd->style & WS_MINIMIZE))
         {
            Flags |= DCX_CLIPCHILDREN;
         }
         /* If minized with icon in the set, we are forced to be cheap! */
         if (Wnd->style & WS_MINIMIZE && Wnd->pcls->spicn)
         {
            Flags |= DCX_CACHE;
         }
      }
      else
      {
         if (Wnd->style & WS_CLIPSIBLINGS) Flags |= DCX_CLIPSIBLINGS;
         Flags |= DCX_CACHE;
      }
   }

   if (Flags & DCX_WINDOW) Flags &= ~DCX_CLIPCHILDREN;

   if (Flags & DCX_NOCLIPCHILDREN)
   {
      Flags |= DCX_CACHE;
      Flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
   }

   Parent = (Wnd ? Wnd->spwndParent : NULL);

   if (NULL == Wnd || !(Wnd->style & WS_CHILD) || NULL == Parent)
   {
      Flags &= ~DCX_PARENTCLIP;
      Flags |= DCX_CLIPSIBLINGS;
   }

   /* It seems parent clip is ignored when clipping siblings or children */
   if (Flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) Flags &= ~DCX_PARENTCLIP;

   if (Flags & DCX_PARENTCLIP)
   {
      if ((Wnd->style & WS_VISIBLE) &&
          (Parent->style & WS_VISIBLE))
      {
         Flags &= ~DCX_CLIPCHILDREN;
         if (Parent->style & WS_CLIPSIBLINGS)
         {
            Flags |= DCX_CLIPSIBLINGS;
         }
      }
   }

   // Window nz, check to see if we still own this or it is just cheap wine tonight.
   if (!(Flags & DCX_CACHE))
   {
      if ( Wnd->head.pti != GetW32ThreadInfo())
         Flags |= DCX_CACHE; // Ah~ Not Powned! Forced to be cheap~
   }

   DcxFlags = Flags & DCX_CACHECOMPAREMASK;

   if (Flags & DCX_CACHE)
   { // Scan the cheap wine list for our match.
      DCE* DceEmpty = NULL;
      DCE* DceUnused = NULL;
      KeEnterCriticalRegion();
      ListEntry = LEDce.Flink;
      while (ListEntry != &LEDce)
      {
         Dce = CONTAINING_RECORD(ListEntry, DCE, List);
         ListEntry = ListEntry->Flink;
//
// The way I understand this, you can have more than one DC per window.
// Only one Owned if one was requested and saved and one Cached.
//
         if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)
         {
            DceUnused = Dce;
            if (Dce->DCXFlags & DCX_DCEEMPTY)
            {
               DceEmpty = Dce;
            }
            else if (Dce->hwndCurrent == (Wnd ? Wnd->head.h : NULL) &&
                     ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags))
            {
               UpdateClipOrigin = TRUE;
               break;
            }
         }
         Dce = NULL; // Loop issue?
      }
      KeLeaveCriticalRegion();

      Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;

      if (Dce == NULL)
      {
         Dce = DceAllocDCE(NULL, DCE_CACHE_DC);
      }
      if (Dce == NULL) return NULL;

      Dce->hwndCurrent = (Wnd ? Wnd->head.h : NULL);
      Dce->pwndOrg = Dce->pwndClip = Wnd;
   }
   else // If we are here, we are POWNED or having CLASS.
   {
      KeEnterCriticalRegion();
      ListEntry = LEDce.Flink;
      while (ListEntry != &LEDce)
      {
          Dce = CONTAINING_RECORD(ListEntry, DCE, List);
          ListEntry = ListEntry->Flink;

          // Skip Cache DCE entries.
          if (!(Dce->DCXFlags & DCX_CACHE))
          {
             // Check for Window handle than HDC match for CLASS.
             if (Dce->hwndCurrent == Wnd->head.h)
             {
                bUpdateVisRgn = FALSE;
                break;
             }
             else if (Dce->hDC == hDC) break;
          }
          Dce = NULL; // Loop issue?
      }
      KeLeaveCriticalRegion();

      if (Dce == NULL)
      {
         return(NULL);
      }

      if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) &&
           (Dce->DCXFlags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) )
      {
         DceDeleteClipRgn(Dce);
      }
   }
// First time use hax, need to use DceAllocDCE during window display init.
   if (NULL == Dce)
   {
      return(NULL);
   }

   if (!GreIsHandleValid(Dce->hDC))
   {
      ERR("FIXME: Got DCE with invalid hDC! %p\n", Dce->hDC);
      Dce->hDC = DceCreateDisplayDC();
      /* FIXME: Handle error */
   }

   Dce->DCXFlags = Flags | DCX_DCEBUSY;

   /*
    * Bump it up! This prevents the random errors in wine dce tests and with
    * proper bits set in DCX_CACHECOMPAREMASK.
    * Reference:
    *   http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html
    *   http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html
    */
   RemoveEntryList(&Dce->List);
   InsertHeadList(&LEDce, &Dce->List);

   /* Introduced in rev 6691 and modified later. */
   if ( (Flags & DCX_INTERSECTUPDATE) && !ClipRegion )
   {
      Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN;
      Dce->DCXFlags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN;
      ClipRegion = Wnd->hrgnUpdate;
      bUpdateVisRgn = TRUE;
   }

   if (ClipRegion == HRGN_WINDOW)
   {
      if (!(Flags & DCX_WINDOW))
      {
         Dce->hrgnClip = NtGdiCreateRectRgn(
             Wnd->rcClient.left,
             Wnd->rcClient.top,
             Wnd->rcClient.right,
             Wnd->rcClient.bottom);
      }
      else
      {
          Dce->hrgnClip = NtGdiCreateRectRgn(
              Wnd->rcWindow.left,
              Wnd->rcWindow.top,
              Wnd->rcWindow.right,
              Wnd->rcWindow.bottom);
      }
      Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;
      bUpdateVisRgn = TRUE;
   }
   else if (ClipRegion != NULL)
   {
      if (Dce->hrgnClip != NULL)
      {
         ERR("Should not be called!!\n");
         GreDeleteObject(Dce->hrgnClip);
         Dce->hrgnClip = NULL;
      }
      Dce->hrgnClip = ClipRegion;
      bUpdateVisRgn = TRUE;
   }

   if (IntGdiSetHookFlags(Dce->hDC, DCHF_VALIDATEVISRGN)) bUpdateVisRgn = TRUE;

   DceSetDrawable(Wnd, Dce->hDC, Flags, UpdateClipOrigin);

   if (bUpdateVisRgn) DceUpdateVisRgn(Dce, Wnd, Flags);

   if (Dce->DCXFlags & DCX_CACHE)
   {
      TRACE("ENTER!!!!!! DCX_CACHE!!!!!!   hDC-> %p\n", Dce->hDC);
      // Need to set ownership so Sync dcattr will work.
      GreSetDCOwner(Dce->hDC, GDI_OBJ_HMGR_POWNED);
      Dce->ptiOwner = GetW32ThreadInfo(); // Set the temp owning
   }

   if ( Wnd &&
        Wnd->ExStyle & WS_EX_LAYOUTRTL &&
       !(Flags & DCX_KEEPLAYOUT) )
   {
      NtGdiSetLayout(Dce->hDC, -1, LAYOUT_RTL);
   }

   if (Dce->DCXFlags & DCX_PROCESSOWNED)
   {
      ppi = PsGetCurrentProcessWin32Process();
      ppi->W32PF_flags |= W32PF_OWNDCCLEANUP;
      Dce->ptiOwner = NULL;
      Dce->ppiOwner = ppi;
   }

   return(Dce->hDC);
}