Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Задачи по C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

LexVel

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

/*++
Module Name:
 
    VUSB.C
 
Abstract:
 
    This module contains the entry points for a virtual USB bus driver.
 
Environment:
 
    kernel mode only
 
Revision History:
 
 
--*/
 
#include <stdarg.h>
#include <ntddk.h>
#include <stdio.h>
#include ".\Include\driver.h"
#include "vusb.h"
 
//
// Global Debug Level
//
 
ULONG VUsbDebugLevel = BUS_DEFAULT_DEBUG_OUTPUT_LEVEL;
 
GLOBALS Globals;
 
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, Bus_DriverUnload)
#pragma alloc_text (PAGE, Bus_CreateClose)
#pragma alloc_text (PAGE, Bus_IoCtl)
#ifdef DEBUG_FULL
#pragma alloc_text (PAGE, PrintBufferContent)
#pragma alloc_text (PAGE, LogMessage)
#endif
#endif
 
NTSTATUS
DriverEntry (
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath
    )
/*++
Routine Description:
 
    Initialize the driver dispatch table.  
 
Arguments:
 
    DriverObject - pointer to the driver object
 
    RegistryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.
 
Return Value:
 
  NT Status Code
 
--*/
{
 
    Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Driver Entry\n"));
 
    //
    // Save the RegistryPath
    //
 
    Globals.RegistryPath.MaximumLength = RegistryPath->Length +
                                          sizeof(UNICODE_NULL);
    Globals.RegistryPath.Length = RegistryPath->Length;
    Globals.RegistryPath.Buffer = ExAllocatePoolWithTag(
                                       PagedPool,
                                       Globals.RegistryPath.MaximumLength,
                                       VUSB_POOL_TAG
                                       );    
 
    if (!Globals.RegistryPath.Buffer) {
 
        return STATUS_INSUFFICIENT_RESOURCES;
    }
     
    RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath);
 
    //
    // Set entry points into the driver
    //
    DriverObject->MajorFunction [IRP_MJ_CREATE] =
    DriverObject->MajorFunction [IRP_MJ_CLOSE]  = Bus_CreateClose;
    DriverObject->MajorFunction [IRP_MJ_PNP]    = Bus_PnP;
    DriverObject->MajorFunction [IRP_MJ_POWER]  = Bus_Power;
    DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = Bus_IoCtl;
    DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = Bus_HandleUSBIoCtl;
    DriverObject->DriverUnload = Bus_DriverUnload;
    DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
 
    return STATUS_SUCCESS;
}
 
NTSTATUS
Bus_CreateClose (
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:
 
    Some outside source is trying to create a file against us.
 
    If this is for the FDO (the bus itself) then the caller  
    is trying to open the proprietary connection to tell us  
    to enumerate or remove a device.
 
    If this is for the PDO (an object on the bus) then this  
    is a client that wishes to use the VUSB device.
     
Arguments:
 
   DeviceObject - pointer to a device object.
 
   Irp - pointer to an I/O Request Packet.
 
Return Value:
 
   NT status code
 
--*/
{
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status;
    PFDO_DEVICE_DATA    fdoData;
 
    PAGED_CODE ();
 
    fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
 
    status = STATUS_INVALID_DEVICE_REQUEST;
    Irp->IoStatus.Information = 0;
     
    //
    // If it's not for the FDO. We don't allow create/close on PDO
    //  
    if (fdoData->IsFDO) {
         
        //
        // Increment IO count on FDO
        //
        Bus_IncIoCount (fdoData);
         
        //
        // Check to see whether the bus is removed
        //
       
        if (fdoData->DevicePnPState == Deleted){          
            status = STATUS_DELETE_PENDING;
        } else {
 
            irpStack = IoGetCurrentIrpStackLocation (Irp);
 
            switch (irpStack->MajorFunction) {
            case IRP_MJ_CREATE:
                Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Create \n"));
                status = STATUS_SUCCESS;
                break;
 
            case IRP_MJ_CLOSE:
                Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Close \n"));
                status = STATUS_SUCCESS;
                break;
             default:
                break;
            }  
        }
         
    }
 
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
    //
    // Decrement IO count on FDO
    //
    if (fdoData->IsFDO)
        Bus_DecIoCount (fdoData);
 
    return status;
}
 
NTSTATUS
Bus_IoCtl (
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:
 
    Handle user mode PlugIn, UnPlug and device Eject requests.
 
Arguments:
 
   DeviceObject - pointer to a device object.
 
   Irp - pointer to an I/O Request Packet.
 
Return Value:
 
   NT status code
 
--*/
{
    PIO_STACK_LOCATION      irpStack;
    NTSTATUS                status;
    ULONG                   inlen, outlen;
    PFDO_DEVICE_DATA        fdoData;
    PVOID                   buffer;
 
    PAGED_CODE ();
     
    fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
 
    //
    // We only take Device Control requests for the FDO.
    // That is the bus itself.
    //
 
    if (!fdoData->IsFDO) {
     
        //
        // These commands are only allowed to go to the FDO.
        //    
        status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
 
    }
 
    //
    // Check to see whether the bus is removed
    //
     
    if (fdoData->DevicePnPState == Deleted) {
        Irp->IoStatus.Status = status = STATUS_DELETE_PENDING;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }
     
    Bus_IncIoCount (fdoData);
     
    irpStack = IoGetCurrentIrpStackLocation (Irp);
 
    buffer = Irp->AssociatedIrp.SystemBuffer;  
    inlen = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outlen = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
 
    status = STATUS_INVALID_PARAMETER;
     
    switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_VUSB_PLUGIN_HARDWARE:
        if ((inlen == outlen) &&
            //
            // Make sure it has at least two nulls and the size  
            // field is set to the declared size of the struct
            //
            ((sizeof (VUSB_PLUGIN_HARDWARE) + sizeof(UNICODE_NULL) * 2) <=
             inlen) &&
 
            //
            // The size field should be set to the sizeof the struct as declared
            // and *not* the size of the struct plus the multi_sz
            //
            (sizeof (VUSB_PLUGIN_HARDWARE) ==
             ((PVUSB_PLUGIN_HARDWARE) buffer)->Size)) {
 
            Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("PlugIn called\n"));
 
            status= Bus_PlugInDevice((PVUSB_PLUGIN_HARDWARE)buffer,
                                inlen, fdoData);
            if (NT_SUCCESS (status))
                IoInvalidateDeviceRelations (fdoData->UnderlyingPDO, BusRelations);
 
            Irp->IoStatus.Information = outlen;
 
        }
        break;
 
    case IOCTL_VUSB_UNPLUG_HARDWARE:
 
        if ((sizeof (VUSB_UNPLUG_HARDWARE) == inlen) &&
            (inlen == outlen) &&
            (((PVUSB_UNPLUG_HARDWARE)buffer)->Size == inlen)) {
 
            Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("UnPlug called\n"));
 
            status= Bus_UnPlugDevice(
                    (PVUSB_UNPLUG_HARDWARE)buffer, fdoData);
            Irp->IoStatus.Information = outlen;
 
        }
        break;
 
    case IOCTL_VUSB_EJECT_HARDWARE:
     
        if ((sizeof (VUSB_EJECT_HARDWARE) == inlen) &&
            (inlen == outlen) &&
            (((PVUSB_EJECT_HARDWARE)buffer)->Size == inlen)) {
 
            Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("Eject called\n"));
 
            status= Bus_EjectDevice((PVUSB_EJECT_HARDWARE)buffer, fdoData);
            Irp->IoStatus.Information = outlen;
 
        }
        break;    
 
    default:
        break; // default status is STATUS_INVALID_PARAMETER
    }
 
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    Bus_DecIoCount (fdoData);
    return status;
}
 
VOID
Bus_DriverUnload (
    IN PDRIVER_OBJECT DriverObject
    )
/*++
Routine Description:
    Clean up everything we did in driver entry.
 
Arguments:
 
   DriverObject - pointer to this driverObject.
 
 
Return Value:
 
--*/
{
    PAGED_CODE ();
 
    Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Unload\n"));
     
    //
    // All the device objects should be gone.
    //
 
    ASSERT (NULL == DriverObject->DeviceObject);
 
    //
    // Here we free all the resources allocated in the DriverEntry
    //
 
    if(Globals.RegistryPath.Buffer)
        ExFreePool(Globals.RegistryPath.Buffer);    
         
    return;
}
 
VOID
Bus_IncIoCount (
    IN  PFDO_DEVICE_DATA   FdoData
    )    
 
/*++
 
Routine Description:
 
    This routine increments the number of requests the device receives
     
 
Arguments:
 
    FdoData - pointer to the FDO device extension.
     
Return Value:
 
    VOID
 
--*/
 
{
 
    LONG            result;
 
 
    result = InterlockedIncrement(&FdoData->OutstandingIO);
 
    ASSERT(result > 0);
    //
    // Need to clear StopEvent (when OutstandingIO bumps from 1 to 2)  
    //
    if (result == 2) {
        //
        // We need to clear the event
        //
        KeClearEvent(&FdoData->StopEvent);
    }
 
    return;
}
 
VOID
Bus_DecIoCount(
    IN  PFDO_DEVICE_DATA  FdoData
    )    
 
/*++
 
Routine Description:
 
    This routine decrements as it complete the request it receives
 
Arguments:
 
    FdoData - pointer to the FDO device extension.
     
Return Value:
 
    VOID
 
--*/
{
 
    LONG            result;
     
    result = InterlockedDecrement(&FdoData->OutstandingIO);
 
    ASSERT(result >= 0);
 
    if (result == 1) {
        //
        // Set the stop event. Note that when this happens
        // (i.e. a transition from 2 to 1), the type of requests we  
        // want to be processed are already held instead of being  
        // passed away, so that we can't "miss" a request that
        // will appear between the decrement and the moment when
        // the value is actually used.
        //
 
        KeSetEvent (&FdoData->StopEvent, IO_NO_INCREMENT, FALSE);
         
    }
     
    if (result == 0) {
 
        //
        // The count is 1-biased, so it can be zero only if an  
        // extra decrement is done when a remove Irp is received  
        //
 
        ASSERT(FdoData->DevicePnPState == Deleted);
 
        //
        // Set the remove event, so the device object can be deleted
        //
 
        KeSetEvent (&FdoData->RemoveEvent, IO_NO_INCREMENT, FALSE);
         
    }
 
    return;
}
 
#ifdef DEBUG_FULL
void PrintBufferContent(OUT PWCHAR outStr, UCHAR *buf, LONG length) {
/*++
Routine Description:
 
   Print buffer content in hex format into string
 
Arguments:
 
   outStr - ptr to output string buffer
 
   buf - ptr to buffer
 
   length - length of buffer
 
Return Value:
 
   none
 
--*/
    PWCHAR tmpBuf;
    LONG i;
    // Check parameters
    if (!buf) {
       swprintf(outStr, L"NULL (ptr to data)");
       return;
    }
    if (length<=0) {
       swprintf(outStr, L"NULL (length)");
       return;
    }
 
    // Create string
    outStr[0]=0;
    outStr[1]=0;
    outStr[2]=0;
    outStr[3]=0;
    tmpBuf = ExAllocatePoolWithTag (PagedPool, 512, VUSB_POOL_TAG);
    if (!tmpBuf)
       return;
    for (i=0; i<length ; i++) {
        swprintf(tmpBuf, L"%02X ", (ULONG) ((UCHAR *)buf)[i]);
        wcscat(outStr, tmpBuf);                              
    }
 
    ExFreePool(tmpBuf);
}
 
NTSTATUS LogMessage(PCHAR szFormat, ...) {
/*++
Routine Description:
 
   Log msg into debug console and file
 
Arguments:
 
   szFormat - message format string
 
   ... - data
 
Return Value:
 
   NT status code
 
--*/
    ULONG Length;
    char messagebuf[1024];
    va_list va;
    IO_STATUS_BLOCK  IoStatus;
    OBJECT_ATTRIBUTES objectAttributes;
    NTSTATUS status;
    HANDLE FileHandle;
    UNICODE_STRING fileName;
     
    //format the string
    va_start(va,szFormat);
    _vsnprintf(messagebuf,sizeof(messagebuf),szFormat,va);
    va_end(va);
     
    //get a handle to the log file object
    fileName.Buffer = NULL;
    fileName.Length = 0;
    fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL);
    fileName.Buffer = ExAllocatePool(PagedPool,
                                     fileName.MaximumLength);
    if (!fileName.Buffer) {
        DbgPrint ("LogMessageInFile: FAIL. ExAllocatePool Failed.\n");
        return FALSE;
    }
    RtlZeroMemory(fileName.Buffer, fileName.MaximumLength);
    status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME);
     
    InitializeObjectAttributes (&objectAttributes,
                                (PUNICODE_STRING)&fileName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL );
     
    status = ZwCreateFile( &FileHandle,
                           FILE_APPEND_DATA,
                           &objectAttributes,
                           &IoStatus,
                           0,  
                           FILE_ATTRIBUTE_NORMAL,
                           FILE_SHARE_WRITE,
                           FILE_OPEN_IF,
                           FILE_SYNCHRONOUS_IO_NONALERT,
                           NULL,      
                           0 );
     
    if( NT_SUCCESS(status) ) {
        CHAR buf[1024];
         
        sprintf(buf,"%s",messagebuf);
         
        //format the string to make sure it appends a newline carrage-return to the  
        //end of the string.
        Length=strlen(buf);
        if( buf[Length-1]=='\n' ) {
            buf[Length-1]='\r';
            strcat(buf,"\n");
            Length++;
        } else {
            strcat(buf,"\r\n");
            Length+=2;
        }
         
        DbgPrint("%s", buf);  
 
        ZwWriteFile( FileHandle, NULL, NULL, NULL, &IoStatus, buf, Length, NULL, NULL );
         
        ZwClose( FileHandle );
    }
 
    if( fileName.Buffer ) {
        ExFreePool (fileName.Buffer);
    }
 
    return STATUS_SUCCESS;
}
#endif

Всего записей: 10074 | Зарегистр. 24-04-2007 | Отправлено: 20:35 18-03-2012
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Задачи по C/С++


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru