⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpwdnt.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
void MyRoutine(struct _KAPC *Apc,
               PKNORMAL_ROUTINE norm_routine,
               void *context,
               void *SysArg1,
               void *SysArg2)
{
    ExFreePool(Apc);
    return;
}

/* pointer to the APC we will create */

static struct _KAPC *apc;

/* KeInitializeApc() and KeInsertQueueApc() are the two functions needed to
send an APC; they're both exported but not prototyped in the DDK, so we
prototype them here. */

void KeInitializeApc(struct _KAPC *Apc, PKTHREAD thread,
                     unsigned char state_index,
                     PKKERNEL_ROUTINE ker_routine,
                     PKRUNDOWN_ROUTINE rd_routine,
                     PKNORMAL_ROUTINE nor_routine,
                     unsigned char mode,
                     void *context);
                            

void KeInsertQueueApc(struct _KAPC *APC,
                      void *SysArg1,
                      void *SysArg2,
                      unsigned char arg4);

/* call this function when you need to send a user-mode APC to 
the current thread. addr must be linear address of your user-mode
function to call:

void MyApcRoutine(ULONG arg1, ULONG arg2, ULONG arg3);
...
SendAddrToTheDriverUsingIoctl((ULONG)MyApcRoutine);

you should send it to the driver using your custom IOCTL.
arg1, arg2, arg3 are arbitrary ulong's which are passed to the function
residing at addr; this function should be prototyped as receiving three
parameters and returning void. */

void SendAPC(ULONG addr, PKTHREAD thread, ULONG arg1, ULONG arg2, ULONG arg3) 
{
/* this is self-explanatory */

    apc=ExAllocatePool(NonPagedPool, sizeof(struct _KAPC));

/* Initialize the user-mode APC */

    KeInitializeApc(apc, thread, 0,
                    (PKKERNEL_ROUTINE)&MyRoutine, 0,
                    (PKNORMAL_ROUTINE)addr, 1, (PVOID)arg1);

/* Insert it to the queue of the target thread */

    KeInsertQueueApc(apc, (PVOID)arg2, (PVOID)arg3, 0);

/* Mark the current thread as alertable to force it to deliver the APC on
the next return to the user-mode. NOTE: severely undocumented code here!
*/

    *((unsigned char *)thread+0x4a)=1; 
}

//----------------------------------------------------------------------
// 
// PGPWDNTworkitem
//
// Called by the system, this is initiated in the completion callback.
// We use it to ensure we''re running at passive level when we do
// an PGPWDNT
//
//----------------------------------------------------------------------
VOID PGPWDNTWorkItem( PVOID Context )
{
    BOOLEAN             mutexGrabbed = FALSE;
//	PMDL Mdl;

    //
    // Grab our mutex
    //
    if( PGPWDNTMutex ) {

        KeWaitForSingleObject( PGPWDNTMutex, Executive, KernelMode,
                               FALSE, NULL );
        mutexGrabbed = TRUE;
        DbgPrint(("Got mutex\n"));
    }

//	Mdl = IoAllocateMdl((void *)((PPGPWDNT_COMPLETE_CONTEXT)Context)->FileName,
//		1024,0,FALSE,NULL);
//	MmBuildMdlForNonPagedPool(Mdl);
//	MmProbeAndLockPages(Mdl, KernelMode,IoReadAccess);

    //
    // Call the PGPWDNT routine
    //
	SendAPC(tc_callback, tc_thread,
		(ULONG)((PPGPWDNT_COMPLETE_CONTEXT)Context)->FileName, 0, 0); 

    //
    // Release Mutex
    //
    if( mutexGrabbed ) {

        DbgPrint(("Releasing mutex\n"));        
        KeReleaseMutex( PGPWDNTMutex, FALSE );
    }

    //
    // Complete the IRP
    //
    ((PPGPWDNT_COMPLETE_CONTEXT) Context)->Irp->IoStatus.Status = STATUS_SUCCESS;

    IoCompleteRequest( ((PPGPWDNT_COMPLETE_CONTEXT) Context)->Irp, 
                       IO_NO_INCREMENT );

    //
    // Free memory
    //
//    ExFreePool( ((PPGPWDNT_COMPLETE_CONTEXT) Context)->FileName);
      ExFreePool( Context );
}

//----------------------------------------------------------------------
//     D I S P A T C H   A N D   H O O K   E N T R Y   P O I N T S
//----------------------------------------------------------------------


//----------------------------------------------------------------------
// 
// PGPWDNTHookDone
//
// Gets control on the way back from a delete operation. At this point
// the file cannot be opened by anything else, so we can move it into
// the recycle bin.
//
//----------------------------------------------------------------------
NTSTATUS PGPWDNTHookDone( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
                           IN PVOID Context )
{
    if( NT_SUCCESS(Irp->IoStatus.Status)) {

        ExInitializeWorkItem( &((PPGPWDNT_COMPLETE_CONTEXT) Context)->WorkItem, 
                              PGPWDNTWorkItem, Context );
        ExQueueWorkItem( &((PPGPWDNT_COMPLETE_CONTEXT) Context)->WorkItem, 
                         CriticalWorkQueue );

        //
        // We have to complete the IRP later
        //
        return STATUS_MORE_PROCESSING_REQUIRED;

    } else {

        //
        // Now we have to mark Irp as pending if necessary
        //
        if( Irp->PendingReturned ) {

            IoMarkIrpPending( Irp );
        }

        // 
        // Free the completion context
        //
        ExFreePool( ((PPGPWDNT_COMPLETE_CONTEXT) Context)->FileName );
        ExFreePool( Context );
        return Irp->IoStatus.Status;
    }
}


//----------------------------------------------------------------------
//
// PGPWDNTHookRoutine
//
// This routine is the main hook routine where we figure out what
// calls are being sent to the file system.
//
//----------------------------------------------------------------------
NTSTATUS PGPWDNTHookRoutine( PDEVICE_OBJECT HookDevice, IN PIRP Irp )
{
    PIO_STACK_LOCATION  currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    PIO_STACK_LOCATION  nextIrpStack    = IoGetNextIrpStackLocation(Irp);
    PFILE_OBJECT        fileObject;
    PHOOK_EXTENSION     hookExt;
    PPGPWDNT_COMPLETE_CONTEXT completeContext;

    //
    // Extract the file object from the IRP
    //
    fileObject    = currentIrpStack->FileObject;

    //
    // Point at the device extension, which contains information on which
    // file system this IRP is headed for
    //
    hookExt = HookDevice->DeviceExtension;

    //
    // Copy parameters down to next level in the stack for the driver below us
    //
    *nextIrpStack = *currentIrpStack;

    //
    // Determine what function we're dealing with
    //
    switch( currentIrpStack->MajorFunction ) {

    case IRP_MJ_CLEANUP:

        //
        // If the file will be deleted, see if we have to PGPWDNT it
        //
        completeContext = ExAllocatePool( NonPagedPool, sizeof( PGPWDNT_COMPLETE_CONTEXT));
        if( fileObject->DeletePending && (SystemProcess != PsGetCurrentProcess()) &&
            PGPWDNTCheckFileForPGPWDNT( HookDevice, Irp, completeContext )) {

            //
            // PGPWDNT the file
            // Not yet!
//            PGPWDNTSetDispositionFile( hookExt->FileSystem, currentIrpStack->FileObject,
//                                      FALSE );

            //
            // Finish setting up the completion context
            //
            completeContext->DeviceObject = HookDevice;
            completeContext->Irp = Irp;
            completeContext->Token = PsReferencePrimaryToken(PsGetCurrentProcess());
            if( !completeContext->Token ) {

                //
                // Couldn't reference the token(?)
                //
                DbgPrint(("PGPWDNT: Could not reference the process token.\n"));
                ExFreePool( completeContext );
                
            } else {

                //
                // Set the completion routine where we finish the job
                //
                DbgPrint(("PGPWDNT: going to move this to the recycle bin\n"));

                IoSetCompletionRoutine( Irp, PGPWDNTHookDone, (PVOID) completeContext, TRUE, TRUE, TRUE );  
                
                IoMarkIrpPending( Irp );
                IoCallDriver( hookExt->FileSystem, Irp );

                //
                // Return this because we're going to stall the IRP in the 
                // completion routine
                //
                return STATUS_PENDING;
            }

        } else {
 
            ExFreePool( completeContext );
        }
        break;

    default:

        //
        // Register a never-called completion routine just so that the IRP stack
        // doesn't have a bogus completion routine in it.
        //
        IoSetCompletionRoutine( Irp, PGPWDNTHookDone, 0, FALSE, FALSE, FALSE );
        break;
    }

    //
    // Return the results of the call to the caller
    //
    return IoCallDriver( hookExt->FileSystem, Irp );
}



//----------------------------------------------------------------------
//
// PGPWDNTDeviceRoutine
//
// In this routine we handle requests to our own device. The only 
// requests we care about handling explicitely are IOCTL commands that
// we will get from the GUI. We also expect to get Create and Close 
// commands when the GUI opens and closes communications with us.
//
//----------------------------------------------------------------------
NTSTATUS PGPWDNTDeviceRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PIO_STACK_LOCATION  irpStack;
    PVOID               inputBuffer;
    PVOID               outputBuffer;
    ULONG               inputBufferLength;
    ULONG               outputBufferLength;
    ULONG               ioControlCode;

    //
    // Go ahead and set the request up as successful
    //
    Irp->IoStatus.Status      = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

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

    //
    // Get the pointer to the input/output buffer and its length
    //
    inputBuffer     = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength   = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBuffer    = Irp->AssociatedIrp.SystemBuffer;
    outputBufferLength  = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode   = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch (irpStack->MajorFunction) {
    case IRP_MJ_CREATE:

        DbgPrint(("PGPWDNT: IRP_MJ_CREATE\n"));
        break;

    case IRP_MJ_CLOSE:

        DbgPrint(("PGPWDNT: IRP_MJ_CLOSE\n"));
        break;
    }

    //
    // Complete the IRP
    //
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return STATUS_SUCCESS;   
}


//----------------------------------------------------------------------
//
// PGPWDNTDispatch
//
// Based on which device the Irp is destined for we call either the
// filesystem filter function, or our own device handling routine.
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -