Beispiel #1
0
/*
 * ptw32_RegisterCancelation() -
 * Must have args of same type as QueueUserAPCEx because this function
 * is a substitute for QueueUserAPCEx if it's not available.
 */
HRESULT XboxThreadRegisterCancelation(DWORD dwThreadId)
{
	BYTE irql = 0;
	HANDLE htObj = NULL;
	HRESULT ret = 0;
	if(ObLookupAnyThreadByThreadId(dwThreadId, &htObj) == 0)
	{
		PKTHREAD kthread = (PKTHREAD)htObj;
		irql = KfAcquireSpinLock(&kthread->Process->ThreadListLock);
		if(kthread->DebugMonitorData != NULL) // this stuff is for devkit...
		{
			if(kthread->DebugMonitorData->dbgContx != NULL)
			{
				kthread->DebugMonitorData->dbgContx->Iar = (DWORD)ptw32_cancel_self;
			}
			else
			{
				kthread->KernelStack[0x39] = (DWORD)ptw32_cancel_self; // Iar
				kthread->KernelStack[0x3A] = (DWORD)ptw32_cancel_self; // Lr << can force both of them if needed be...
			}

		}
	 	else // this stuff is for retail... actually even on devkit this is likely all that is needed
		{
			kthread->KernelStack[0x39] = (DWORD)ptw32_cancel_self; // Iar
			kthread->KernelStack[0x3A] = (DWORD)ptw32_cancel_self; // Lr << can force both of them if needed be...
		}
		KfReleaseSpinLock(&kthread->Process->ThreadListLock, irql);
		ObDereferenceObject(htObj);
	}
	else
		ret = 0x82DA0007;

	return ret; 
}
Beispiel #2
0
//----- (0800130C) --------------------------------------------------------
PDRIVER_ENTRY 
LookupEntryByDrvObj(
	PDRIVER_OBJECT	DriverObject
	)
{
	KIRQL			OldIrql;
	PDRIVER_ENTRY	hashEntry, prevEntry = NULL;

	OldIrql = KfAcquireSpinLock(&HashLock);

	hashEntry = g_pDrvObjList;
	while ( hashEntry )
	{
		if ( hashEntry->DriverObject == DriverObject )
		{
			prevEntry = hashEntry;
			break;
		}

		hashEntry = hashEntry->Next;
	}

	KfReleaseSpinLock(&HashLock, OldIrql);
	return prevEntry;
}
Beispiel #3
0
/*
 * @implemented
 */
VOID
NTAPI
KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
                  PKIRQL OldIrql)
{
    /* Call the fastcall function */
    *OldIrql = KfAcquireSpinLock(SpinLock);
}
Beispiel #4
0
//----- (08000B10) --------------------------------------------------------
VOID __cdecl LogRecord(
	ULONG Sequence, 
	PLARGE_INTEGER time, 
	ULONG DiskNum, 
	PCH format, 
	...
	)
{
	static CHAR     text[1000];
	PENTRY          Entry;
	ULONG           len;
	va_list         arg_ptr;

	KIRQL OldIrql;
	if ( g_bGUIActive )
	{
		if ( g_bStartMon )
		{
			OldIrql = KfAcquireSpinLock(&LogBufferLock);

			va_start( arg_ptr, format );
			len = vsprintf( text, format, arg_ptr );
			va_end( arg_ptr );

			len += 4; len &= 0xFFFFFFFC;

			if (LogBuffer->Len + len + sizeof(*Entry) >= 0x10000)
			{
				DMonNewLogBuffer();		
			}

			Entry = (PENTRY) (LogBuffer->Data + LogBuffer->Len);
			Entry->seq = Sequence;
			Entry->time.QuadPart = time->QuadPart;
			Entry->DiskNum = DiskNum;
			memcpy((void *)Entry->text, text, len);

			LogBuffer->Len += len + (PCHAR)Entry->text - (PCHAR)Entry;

			KfReleaseSpinLock(&LogBufferLock, OldIrql);
		}
	}
}
Beispiel #5
0
//----- (0800134A) --------------------------------------------------------
VOID 
AddDeviceToHookEntry(
	PDEVICE_OBJECT	DeviceObject, 
	ULONG			DiskIndex, 
	ULONG			PartitionIndex
	)
{
	PDEVICE_ENTRY	DevEntry, PreDevEntry = NULL;
	PDEVICE_ENTRY	NewDevEntry;
	PDRIVER_ENTRY	DrvEntry, NewDrvEntry;
	KIRQL			OldIrql;
	ULONG			i;

	OldIrql = KfAcquireSpinLock(&HashLock);
	DevEntry = g_pDevObjList;

	if ( g_pDevObjList )
	{
		while ( DevEntry->DeviceObject != DeviceObject )
		{
			PreDevEntry = DevEntry;
			DevEntry = DevEntry->Next;
			if ( !DevEntry )
				goto NewDev;
		}
		if ( PreDevEntry )
		{
			PreDevEntry->Next = DevEntry->Next;
		}
		else
		{
			g_pDevObjList = DevEntry->Next;
		}
		ExFreePool(DevEntry);
	}

NewDev:
	NewDevEntry = (PDEVICE_ENTRY)ExAllocatePool(0, 0x10);
	if ( NewDevEntry )
	{
		NewDevEntry->DeviceObject	= DeviceObject;
		NewDevEntry->DiskNumber		= PartitionIndex | (DiskIndex << 16);

		DrvEntry = g_pDrvObjList;
		if ( g_pDrvObjList )
		{
			while ( DrvEntry->DriverObject != DeviceObject->DriverObject)
			{
				DrvEntry = DrvEntry->Next;
				if ( !DrvEntry )
					goto NewDrv;
			}

			NewDevEntry->DrvEntry = DrvEntry;
			NewDevEntry->Next = g_pDevObjList;

			g_pDevObjList = NewDevEntry;
		}
		else
		{
NewDrv:
			NewDevEntry->Next = g_pDevObjList;
			g_pDevObjList = NewDevEntry;

			NewDrvEntry = (PDRIVER_ENTRY)ExAllocatePool(0, 0x78);
			if ( NewDrvEntry )
			{
				NewDrvEntry->DriverObject	= DeviceObject->DriverObject;
				NewDevEntry->DrvEntry	= NewDrvEntry;
				NewDrvEntry->Next			= g_pDrvObjList;

				g_pDrvObjList = NewDrvEntry;
				memcpy(NewDrvEntry->DriverDispatch, DeviceObject->DriverObject->MajorFunction, 0x6C);

				for(i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
				{
					if(g_pDriverObject->MajorFunction[i] != g_pDriverObject->MajorFunction[1])
					{
						DeviceObject->DriverObject->MajorFunction[i] = g_pDriverObject->MajorFunction[i];
					}
				}
			}
		}
	}

	KfReleaseSpinLock(&HashLock, OldIrql);
}
Beispiel #6
0
//----- (080015E0) --------------------------------------------------------
NTSTATUS 
DMDeviceIoCtl(
	IN PIRP		Irp, 
	IN PVOID	InputBuffer, 
	IN ULONG	InputBufferLength, 
	OUT PVOID	OutputBuffer, 
	IN ULONG	OutputBufferLength, 
	IN ULONG	IoControlCode
	)
{	
	NTSTATUS            status = STATUS_SUCCESS;
	PLOG_BUFFER         old;
	KIRQL				OldIrql;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	switch ( IoControlCode ) {

	case IOCTL_DMON_ZEROSTATS/*0x83100004*/:
		{
			DbgPrint("Diskmon: zero stats\n");
			OldIrql = KfAcquireSpinLock(&LogBufferLock);

			while ( LogBuffer->Next )  
			{
				old = LogBuffer->Next;
				LogBuffer->Next = old->Next;
				ExFreePool( old );
				NumLogBuffer--;
			}

			LogBuffer->Len = 0;
			Sequence = 0;

			KfReleaseSpinLock(&LogBufferLock, OldIrql);
		}
		break;

	case IOCTL_DMON_GETSTATS/*0x8310000B*/:
		{
			DbgPrint("Diskmon: get stats\n");

			if ( MAX_STORE > OutputBufferLength ) 
			{
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			OldIrql = KfAcquireSpinLock(&LogBufferLock);

			if ( LogBuffer->Len  ||  LogBuffer->Next )
			{
				DMonNewLogBuffer();
				old = DMonOldestLogBuffer();

				KfReleaseSpinLock(&LogBufferLock, OldIrql);

				memcpy(OutputBuffer, old->Data, old->Len);
				Irp->IoStatus.Information = old->Len;

				ExFreePool(old);
			}
			else
			{
				KfReleaseSpinLock(&LogBufferLock, OldIrql);
				Irp->IoStatus.Information = 0;
			}
		}
		break;

	case IOCTL_DMON_STOPFILTER/*0x83100010*/:
		DbgPrint("Diskmon: stop logging\n");

		g_bStartMon = FALSE;
		break;

	case IOCTL_DMON_STARTFILTER/*0x83100014*/:
		DbgPrint("Diskmon: start logging\n");

		g_bStartMon = TRUE;
		break;

	case 0x8310001C:
		g_bUsePerfCounter = *((PBOOLEAN)InputBuffer);
		break;

	case IOCTL_DMON_VERSION/*0x83100020*/://Version
		if ( OutputBufferLength >= 4 && OutputBuffer )
		{
			*(PULONG)OutputBuffer = DMONVERSION;
			Irp->IoStatus.Information = 4;
		}
		else
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
		}
		break;

	case 0x83100024:
		*(PULONG)OutputBuffer = 2;

		if ( g_WriteCount || g_bWrite )
		{
			*(PULONG)OutputBuffer = 1;
		}
		else if ( g_ReadCount || g_bRead )
		{
			*(PULONG)OutputBuffer = 0;
		}
		g_bRead = FALSE;
		g_bWrite = FALSE;

		Irp->IoStatus.Information = 4;
		break;

	default:
		DbgPrint("Diskmon: unknown IRP_MJ_DEVICE_CONTROL\n");
		Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}

	status = Irp->IoStatus.Status;
	IofCompleteRequest(Irp, 0);
	return status;
}
Beispiel #7
0
VOID
IoFreeMapRegisters(
   PADAPTER_OBJECT AdapterObject,
   PVOID MapRegisterBase,
   ULONG NumberOfMapRegisters
   )
/*++

Routine Description:

   This routine deallocates the map registers for the adapter.  If there are
   any queued adapter waiting for an attempt is made to allocate the next
   entry.

Arguments:

   AdapterObject - The adapter object to where the map register should be
        returned.

   MapRegisterBase - The map register base of the registers to be deallocated.

   NumberOfMapRegisters - The number of registers to be deallocated.

Return Value:

   None

--+*/
{
   PADAPTER_OBJECT MasterAdapter;
   LONG MapRegisterNumber;
   PWAIT_CONTEXT_BLOCK Wcb;
   PLIST_ENTRY Packet;
   IO_ALLOCATION_ACTION Action;
   KIRQL Irql;


    //
    // Begin by getting the address of the master adapter.
    //

    if (AdapterObject->MasterAdapter != NULL && MapRegisterBase != NULL) {

        MasterAdapter = AdapterObject->MasterAdapter;

    } else {

        //
        // There are no map registers to return.
        //

        return;
    }

   //
   // Strip no scatter/gather flag.
   //

   MapRegisterBase = (PVOID) ((ULONG) MapRegisterBase & ~NO_SCATTER_GATHER);

   MapRegisterNumber = (PTRANSLATION_ENTRY) MapRegisterBase -
        (PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase;

   //
   // Acquire the master adapter spinlock which locks the adapter queue and the
   // bit map for the map registers.
   //

   Irql = KfAcquireSpinLock(&MasterAdapter->SpinLock);

   //
   // Return the registers to the bit map.
   //

   RtlClearBits( MasterAdapter->MapRegisters,
                 MapRegisterNumber,
                 NumberOfMapRegisters
                 );

   //
   // Process any requests waiting for map registers in the adapter queue.
   // Requests are processed until a request cannot be satisfied or until
   // there are no more requests in the queue.
   //

   while(TRUE) {

      if ( IsListEmpty(&MasterAdapter->AdapterQueue) ){
         break;
      }

      Packet = RemoveHeadList( &MasterAdapter->AdapterQueue );
      AdapterObject = CONTAINING_RECORD( Packet,
                                         ADAPTER_OBJECT,
                                         AdapterQueue
                                         );
      Wcb = AdapterObject->CurrentWcb;

      //
      // Attempt to allocate map registers for this request. Use the previous
      // register base as a hint.
      //

      MapRegisterNumber = RtlFindClearBitsAndSet( MasterAdapter->MapRegisters,
                                               AdapterObject->NumberOfMapRegisters,
                                               MasterAdapter->NumberOfMapRegisters
                                               );

      if (MapRegisterNumber == -1) {

         //
         // There were not enough free map registers.  Put this request back on
         // the adapter queue where is came from.
         //

         InsertHeadList( &MasterAdapter->AdapterQueue,
                         &AdapterObject->AdapterQueue
                         );

         break;

      }

     KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );

     AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY)
        MasterAdapter->MapRegisterBase + MapRegisterNumber);

     //
     // Set the no scatter/gather flag if scatter/gather not
     // supported.
     //

     if (!AdapterObject->ScatterGather) {

        AdapterObject->MapRegisterBase = (PVOID)
            ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);

     }

     //
     // Invoke the driver's execution routine now.
     //

      Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
        Wcb->CurrentIrp,
        AdapterObject->MapRegisterBase,
        Wcb->DeviceContext );

      //
      // If the driver wishes to keep the map registers then set the number
      // allocated to zero and set the action to deallocate object.
      //

      if (Action == DeallocateObjectKeepRegisters) {
          AdapterObject->NumberOfMapRegisters = 0;
          Action = DeallocateObject;
      }

      //
      // If the driver would like to have the adapter deallocated,
      // then deallocate any map registers allocated and then release
      // the adapter object.
      //

      if (Action == DeallocateObject) {

             //
             // The map registers registers are deallocated here rather than in
             // IoFreeAdapterChannel.  This limits the number of times
             // this routine can be called recursively possibly overflowing
             // the stack.  The worst case occurs if there is a pending
             // request for the adapter that uses map registers and whos
             // excution routine decallocates the adapter.  In that case if there
             // are no requests in the master adapter queue, then IoFreeMapRegisters
             // will get called again.
             //

          if (AdapterObject->NumberOfMapRegisters != 0) {

             //
             // Deallocate the map registers and clear the count so that
             // IoFreeAdapterChannel will not deallocate them again.
             //

             Irql = KfAcquireSpinLock( &MasterAdapter->SpinLock );

             RtlClearBits( MasterAdapter->MapRegisters,
                           MapRegisterNumber,
                           AdapterObject->NumberOfMapRegisters
                           );

             AdapterObject->NumberOfMapRegisters = 0;

             KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
          }

          IoFreeAdapterChannel( AdapterObject );
      }

      Irql = KfAcquireSpinLock( &MasterAdapter->SpinLock );

   }

   KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
}
Beispiel #8
0
VOID
IoFreeAdapterChannel(
    IN PADAPTER_OBJECT AdapterObject
    )

/*++

Routine Description:

    This routine is invoked to deallocate the specified adapter object.
    Any map registers that were allocated are also automatically deallocated.
    No checks are made to ensure that the adapter is really allocated to
    a device object.  However, if it is not, then kernel will bugcheck.

    If another device is waiting in the queue to allocate the adapter object
    it will be pulled from the queue and its execution routine will be
    invoked.

Arguments:

    AdapterObject - Pointer to the adapter object to be deallocated.

Return Value:

    None.

--*/

{
    PKDEVICE_QUEUE_ENTRY Packet;
    PWAIT_CONTEXT_BLOCK Wcb;
    PADAPTER_OBJECT MasterAdapter;
    BOOLEAN Busy = FALSE;
    IO_ALLOCATION_ACTION Action;
    KIRQL Irql;
    LONG MapRegisterNumber;

    //
    // Begin by getting the address of the master adapter.
    //

    MasterAdapter = AdapterObject->MasterAdapter;

    //
    // Pull requests of the adapter's device wait queue as long as the
    // adapter is free and there are sufficient map registers available.
    //

    while( TRUE ) {

       //
       // Begin by checking to see whether there are any map registers that
       // need to be deallocated.  If so, then deallocate them now.
       //

       if (AdapterObject->NumberOfMapRegisters != 0) {
           IoFreeMapRegisters( AdapterObject,
                               AdapterObject->MapRegisterBase,
                               AdapterObject->NumberOfMapRegisters
                               );
       }

       //
       // Simply remove the next entry from the adapter's device wait queue.
       // If one was successfully removed, allocate any map registers that it
       // requires and invoke its execution routine.
       //

       Packet = KeRemoveDeviceQueue( &AdapterObject->ChannelWaitQueue );
       if (Packet == NULL) {

           //
           // There are no more requests break out of the loop.
           //

           break;
       }

       Wcb = CONTAINING_RECORD( Packet,
            WAIT_CONTEXT_BLOCK,
            WaitQueueEntry );

       AdapterObject->CurrentWcb = Wcb;
       AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;

        //
        // Check to see whether this driver wishes to allocate any map
        // registers.  If so, then queue the device object to the master
        // adapter queue to wait for them to become available.  If the driver
        // wants map registers, ensure that this adapter has enough total
        // map registers to satisfy the request.
        //

        if (Wcb->NumberOfMapRegisters != 0 &&
            AdapterObject->MasterAdapter != NULL) {

            //
            // Lock the map register bit map and the adapter queue in the
            // master adapter object. The channel structure offset is used as
            // a hint for the register search.
            //

            Irql = KfAcquireSpinLock( &MasterAdapter->SpinLock );

            MapRegisterNumber = -1;

            if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
               MapRegisterNumber = RtlFindClearBitsAndSet( MasterAdapter->MapRegisters,
                                                        Wcb->NumberOfMapRegisters,
                                                        0
                                                        );
            }
            if (MapRegisterNumber == -1) {

               //
               // There were not enough free map registers.  Queue this request
               // on the master adapter where is will wait until some registers
               // are deallocated.
               //

               InsertTailList( &MasterAdapter->AdapterQueue,
                               &AdapterObject->AdapterQueue
                               );
               Busy = 1;

            } else {

                AdapterObject->MapRegisterBase = ((PTRANSLATION_ENTRY)
                    MasterAdapter->MapRegisterBase + MapRegisterNumber);

                //
                // Set the no scatter/gather flag if scatter/gather not
                // supported.
                //

                if (!AdapterObject->ScatterGather) {

                    AdapterObject->MapRegisterBase = (PVOID)
                        ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);

                }
            }

            KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );

        } else {

            AdapterObject->MapRegisterBase = NULL;
            AdapterObject->NumberOfMapRegisters = 0;

        }

        //
        // If there were either enough map registers available or no map
        // registers needed to be allocated, invoke the driver's execution
        // routine now.
        //

        if (!Busy) {
            AdapterObject->CurrentWcb = Wcb;
            Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
                Wcb->CurrentIrp,
                AdapterObject->MapRegisterBase,
                Wcb->DeviceContext );

            //
            // If the execution routine would like to have the adapter
            // deallocated, then release the adapter object.
            //

            if (Action == KeepObject) {

               //
               // This request wants to keep the channel a while so break
               // out of the loop.
               //

               break;

            }

            //
            // If the driver wants to keep the map registers then set the
            // number allocated to 0.  This keeps the deallocation routine
            // from deallocating them.
            //

            if (Action == DeallocateObjectKeepRegisters) {
                AdapterObject->NumberOfMapRegisters = 0;
            }

        } else {

           //
           // This request did not get the requested number of map registers so
           // out of the loop.
           //

           break;
        }
    }
}