Ejemplo n.º 1
0
BOOLEAN
XenLowerBackendInit(
    PXEN_LOWER XenLower)
{
    PCHAR path;
    NTSTATUS status;

    // Note this is split from the XenLowerInit so it can be called on the resume
    // path in case backend values change.

    XXX_TODO("--XT-- All the backend path handling assumes dom0 is the backend, this will change for device domains")
    // XXX TODO all the backend path handling assumes dom0 is the backend. This will
    // not necessarily be true with device domains. The changes to support this go
    // beyond this module though.
    path = XenLowerReadXenstoreValue(XenLower->FrontendPath, "backend");
    if (path == NULL)
    {
        TraceError((__FUNCTION__
            ": XenLowerReadXenstoreValue() failed to return the back end path, fatal.\n"));
        return FALSE;
    }
    status = RtlStringCchCopyA(XenLower->BackendPath,
        sizeof(XenLower->BackendPath),
        path);
    XmFreeMemory(path);
    if (status != STATUS_SUCCESS)
    {
        XenLower->BackendPath[0] = 0;
        TraceError((__FUNCTION__
            ": Failed to copy back end path - status: 0x%x\n", status));
        return FALSE;
    }

    status = xenbus_read_domain_id(XBT_NIL, XenLower->FrontendPath,
        "backend-id", &XenLower->BackendDomid);
    if (!NT_SUCCESS(status))
    {
        TraceWarning((__FUNCTION__
            ": Failed to read backend id from %s (%x), setting to dom0\n",
            XenLower->FrontendPath, status));
        XenLower->BackendDomid = DOMAIN_ID_0();
    }

    // XXX TODO for now we only support a dom0 backend so check that here. Later
    // when we support a device domain for vusb, other domids will be fine.
    XXX_TODO("--XT-- For now we only support a dom0 backend so check that here");
    if (unwrap_DOMAIN_ID(XenLower->BackendDomid) != unwrap_DOMAIN_ID(DOMAIN_ID_0()))
    {
        TraceError((XENTARGET
            ": cannot connect to backend Domid: %d, only dom0 supported currently\n",
            XenLower->BackendDomid));
        return FALSE;
    }

    TraceInfo((__FUNCTION__
        ": XenLower initialized - FrontendPath: %s  BackendPath: %s BackendDomid: %d\n",
        XenLower->FrontendPath, XenLower->BackendPath, unwrap_DOMAIN_ID(XenLower->BackendDomid)));

    return TRUE;
}
Ejemplo n.º 2
0
// Buffer the log entry to the log buffer.
EXTERN_C static NTSTATUS LogpBufferMessage(_In_ const char *Message,
                                           _In_opt_ LogBufferInfo *Info) {
  NT_ASSERT(Info);

  // Acquire a spin lock to add the log safely.
  const auto oldIrql = KeGetCurrentIrql();
  if (oldIrql < DISPATCH_LEVEL) {
    KeAcquireSpinLockRaiseToDpc(&Info->SpinLock);
  }
  NT_ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);

  // Copy the current log to the buffer.
  size_t usedBufferSize = Info->LogBufferTail - Info->LogBufferHead;
  auto status =
      RtlStringCchCopyA(const_cast<char *>(Info->LogBufferTail),
                        LOGP_BUFFER_USABLE_SIZE - usedBufferSize, Message);

  // Update Info.LogMaximumUsage if necessary.
  if (NT_SUCCESS(status)) {
    const auto messageLength = strlen(Message) + 1;
    Info->LogBufferTail += messageLength;
    usedBufferSize += messageLength;
    if (usedBufferSize > Info->LogMaximumUsage) {
      Info->LogMaximumUsage = usedBufferSize;  // Update
    }
  } else {
    Info->LogMaximumUsage = LOGP_BUFFER_SIZE;  // Indicates overflow
  }
  *Info->LogBufferTail = '\0';

  if (oldIrql < DISPATCH_LEVEL) {
    KeReleaseSpinLock(&Info->SpinLock, oldIrql);
  }
  return status;
}
Ejemplo n.º 3
0
BOOLEAN
XenLowerInit(
    PXEN_LOWER XenLower,
    PVOID XenUpper,
    PDEVICE_OBJECT Pdo)
{
    PCHAR path;
    NTSTATUS status;

    XenLower->XenUpper = XenUpper;
    XenLower->Pdo = Pdo;

    //
    // Wait for xenbus to come up.  SMP guests sometimes try and
    // initialise xennet and xenvbd in parallel when they come back
    // from hibernation, and that causes problems.
    //

    if (!xenbus_await_initialisation())
    {
        TraceError((__FUNCTION__ ": xenbus_await_initialisation() failed?\n"));
        return FALSE;
    }

    path = xenbus_find_frontend(Pdo);
    if (path == NULL)
    {
        TraceError((__FUNCTION__
            ": xenbus_find_frontend() failed to return the front end path, fatal.\n"));
        return FALSE;
    }
    status = RtlStringCchCopyA(XenLower->FrontendPath,
        sizeof(XenLower->FrontendPath),
        path);
    XmFreeMemory(path);
    if (status != STATUS_SUCCESS)
    {
        XenLower->FrontendPath[0] = 0;
        TraceError((__FUNCTION__ ": Failed to copy front end path - status: 0x%x\n", status));
        return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 4
0
// Buffer the log entry to the log buffer.
_Use_decl_annotations_ static NTSTATUS LogpBufferMessage(const char *message,
                                                         LogBufferInfo *info) {
  NT_ASSERT(info);

  // Acquire a spin lock to add the log safely.
  KLOCK_QUEUE_HANDLE lock_handle = {};
  const auto old_irql = KeGetCurrentIrql();
  if (old_irql < DISPATCH_LEVEL) {
    KeAcquireInStackQueuedSpinLock(&info->spin_lock, &lock_handle);
  } else {
    KeAcquireInStackQueuedSpinLockAtDpcLevel(&info->spin_lock, &lock_handle);
  }
  NT_ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);

  // Copy the current log to the buffer.
  SIZE_T used_buffer_size = info->log_buffer_tail - info->log_buffer_head;
  auto status =
      RtlStringCchCopyA(const_cast<char *>(info->log_buffer_tail),
                        kLogpBufferUsableSize - used_buffer_size, message);

  // Update info.log_max_usage if necessary.
  if (NT_SUCCESS(status)) {
    const auto message_length = strlen(message) + 1;
    info->log_buffer_tail += message_length;
    used_buffer_size += message_length;
    if (used_buffer_size > info->log_max_usage) {
      info->log_max_usage = used_buffer_size;  // Update
    }
  } else {
    info->log_max_usage = kLogpBufferSize;  // Indicates overflow
  }
  *info->log_buffer_tail = '\0';

  if (old_irql < DISPATCH_LEVEL) {
    KeReleaseInStackQueuedSpinLock(&lock_handle);
  } else {
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock_handle);
  }
  return status;
}
Ejemplo n.º 5
0
NTSTATUS
DiskGenerateDeviceName(
    IN ULONG DeviceNumber,
    OUT PCCHAR *RawName
    )

/*++

Routine Description:

    This routine will allocate a unicode string buffer and then fill it in
    with a generated name for the specified device object.

    It is the responsibility of the user to allocate a UNICODE_STRING structure
    to pass in and to free UnicodeName->Buffer when done with it.

Arguments:

    DeviceObject - a pointer to the device object

    UnicodeName - a unicode string to put the name buffer into

Return Value:

    status

--*/

#define FDO_NAME_FORMAT "\\Device\\Harddisk%d\\DR%d"

{
    CHAR rawName[64] = { 0 };
    NTSTATUS status;

    PAGED_CODE();

        status = RtlStringCchPrintfA(rawName, sizeof(rawName) - 1, FDO_NAME_FORMAT, DeviceNumber,
                                    diskDeviceSequenceNumber++);
        if (!NT_SUCCESS(status)) {
            TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Format FDO name failed with error: 0x%X\n", status));
            return status;
        }

    *RawName = ExAllocatePoolWithTag(PagedPool,
                                     strlen(rawName) + 1,
                                     DISK_TAG_NAME);

    if(*RawName == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = RtlStringCchCopyA(*RawName, strlen(rawName) + 1, rawName);
    if (!NT_SUCCESS(status)) {
        TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Device name copy failed with error: 0x%X\n", status));
        FREE_POOL(*RawName);
        return status;
    }

    TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskGenerateDeviceName: generated \"%s\"\n", rawName));

    return STATUS_SUCCESS;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/*++
* @method: DrvDispatch
*
* @description: IOCTL dispatch routine
*
* @input: IN PDEVICE_OBJECT pDevice, IN PIRP pIrp
*
* @output: NTSTATUS
*
*--*/
NTSTATUS DrvDispatch( IN PDEVICE_OBJECT pDevice, IN PIRP pIrp )
{
    NTSTATUS retVal = STATUS_UNSUCCESSFUL;
    
    __try
    {
        UINT nIndex = 0;
        DWORD dwInBuffSize = 0;
        DWORD dwOutBuffSize = 0;
        PIO_STACK_LOCATION pIoStackIrp = NULL;

        if( MmIsAddressValid( pIrp ) )
        {
            pIoStackIrp = IoGetCurrentIrpStackLocation( pIrp );
        }

        if( MmIsAddressValid( pIoStackIrp ) )
        {
            dwInBuffSize = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
            dwOutBuffSize = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
        }

        switch( pIoStackIrp->Parameters.DeviceIoControl.IoControlCode )
        {
        case IOCTL_OS_VER_INFO:
            {
                // Set OS and SP versions got from usermode, in our globals
                PMYOSVERINFO pOSVerInfo = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pOSVerInfo ) )
                {
                    if( STATUS_SUCCESS == InitGlobals( pOSVerInfo ) )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwInBuffSize;
                    }
                }
            }
            break;

        case IOCTL_GET_DATA_CNT:
            {
                // Get the count of items requested by usermode
                PARKDATACOUNT pArkDataCout = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pArkDataCout ) )
                {
                    switch( pArkDataCout->typeOfArkData )
                    {
                    case eArkDataProcList:
                        {
                            // Get the count of running processes
                            pArkDataCout->dataCount = ScanAndGetProcessCount();
                        }
                        break;

                    case eArkDataDllList:
                        {
                            // Get the count of DLLs
                            pArkDataCout->dataCount = ScanAndGetDllCount( pArkDataCout->miscData );
                        }
                        break;

                    case eArkDataDriverList:
                        {
                            // Get the count of loaded drivers
                            pArkDataCout->dataCount = ScanAndGetDriverCount();
                        }
                        break;

                    case eArkDataSsdtList:
                        {
                            // Get the count of SSDT hooks
                            pArkDataCout->dataCount = ScanAndGetSSDTHooksCount();
                        }
                        break;

                    default:
                        {
                            pArkDataCout->dataCount = 0;
                        }
                        break;
                    }

                    // Set the IO status based on count of items
                    if( pArkDataCout->dataCount > 0 )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = sizeof( ARKDATACOUNT );
                    }
                }
            }
            break;

        case IOCTL_GET_PROCESS:
            {
                // Copy all processes info from our internal list to usermode array
                PARKPROCESS pArkProcData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pArkProcData ) && VALIDATE_LIST_BUFF_SIZE( dwOutBuffSize, ARKPROCESS, eProcList ) )
                {
                    PPROCLISTENTRY pProcListEntry = NULL;
                    while( STATUS_SUCCESS == GetListEntry( eProcList, nIndex, &pProcListEntry ) )
                    {
                        if( MmIsAddressValid( pProcListEntry ) )
                        {
                            pArkProcData[nIndex].procId = pProcListEntry->dwPID;
                            RtlStringCchCopyA( pArkProcData[nIndex].procName, ARKITLIB_STR_LEN, pProcListEntry->szProcName );
                            ++nIndex;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if( nIndex > 0 )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwOutBuffSize;
                    }
                }
                // Free our internal process list
                DelList( eProcList );
            }
            break;

        case IOCTL_GET_DLLS:
            {
                // Copy all DLLs info from our internal list to usermode array
                PARKDLL pArkDllData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pArkDllData ) && VALIDATE_LIST_BUFF_SIZE( dwOutBuffSize, ARKDLL, eDllList ) )
                {
                    PDLLLISTENTRY pDllListEntry = NULL;
                    while( STATUS_SUCCESS == GetListEntry( eDllList, nIndex, &pDllListEntry ) )
                    {
                        if( MmIsAddressValid( pDllListEntry ) )
                        {
                            pArkDllData[nIndex].baseAddr = pDllListEntry->dwBase;
                            RtlStringCchCopyA( pArkDllData[nIndex].dllName, ARKITLIB_STR_LEN, pDllListEntry->szDllName );
                            ++nIndex;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if( nIndex > 0 )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwOutBuffSize;
                    }
                }
                // Free our internal DLL list
                DelList( eDllList );
            }
            break;

        case IOCTL_GET_DRIVERS:
            {
                // Copy all drivers info from our internal list to usermode array
                PARKDRIVER pArkDrvData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pArkDrvData ) && VALIDATE_LIST_BUFF_SIZE( dwOutBuffSize, ARKDRIVER, eDrvList ) )
                {
                    PDRIVERLISTENTRY pDrvListEntry = NULL;
                    while( STATUS_SUCCESS == GetListEntry( eDrvList, nIndex, &pDrvListEntry ) )
                    {
                        if( MmIsAddressValid( pDrvListEntry ) )
                        {
                            pArkDrvData[nIndex].baseAddr = pDrvListEntry->dwBase;
                            pArkDrvData[nIndex].endAddr = pDrvListEntry->dwEnd;
                            pArkDrvData[nIndex].entryPoint = pDrvListEntry->dwEntryPoint;
                            RtlStringCchCopyA( pArkDrvData[nIndex].driverName, ARKITLIB_STR_LEN, pDrvListEntry->szDrvName );
                            ++nIndex;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if( nIndex > 0 )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwOutBuffSize;
                    }
                }
                // Free our internal driver list
                DelList( eDrvList );
            }
            break;

        case IOCTL_GET_SSDTHOOKS:
            {
                // Copy all SSDT hooks info from our internal list to usermode array
                PARKSSDTHOOK pArkSsdtData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pArkSsdtData ) && VALIDATE_LIST_BUFF_SIZE( dwOutBuffSize, ARKSSDTHOOK, eSsdtList ) )
                {
                    PSSDTHOOKLISTENTRY pSsdtListEntry = NULL;
                    while( STATUS_SUCCESS == GetListEntry( eSsdtList, nIndex, &pSsdtListEntry ) )
                    {
                        if( MmIsAddressValid( pSsdtListEntry ) )
                        {
                            pArkSsdtData[nIndex].unSsdtIndex = pSsdtListEntry->unIndex;
                            pArkSsdtData[nIndex].baseAddr = pSsdtListEntry->dwBase;
                            pArkSsdtData[nIndex].endAddr = pSsdtListEntry->dwEnd;
                            pArkSsdtData[nIndex].hookAddr = pSsdtListEntry->dwHookAddr;
                            RtlStringCchCopyA( pArkSsdtData[nIndex].driverName, ARKITLIB_STR_LEN, pSsdtListEntry->szDrvName );
                            ++nIndex;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if( nIndex > 0 )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwOutBuffSize;
                    }
                }
                // Free our internal driver and SSDT list
                DelList( eDrvList );
                DelList( eSsdtList );
            }
            break;

        case IOCTL_GET_SYSENTERHOOK:
            {
                // Copy sysenter hook data to usermode buffer
                PARKSYSENTERHOOK pSysenterHookData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pSysenterHookData ) )
                {
                    if( ScanAndGetSysenterHook( pSysenterHookData ) )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwOutBuffSize;
                    }
                }

                // Free driver list
                DelList( eDrvList );
            }
            break;

        case IOCTL_GET_KINLINEHOOK:
            {
                PARKINLINEHOOK pKernelFuncData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pKernelFuncData ) )
                {
                    if( ScanFunctionInlineHook( pKernelFuncData ) )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwOutBuffSize;
                    }
                }
            }
            break;

        case IOCTL_NT_API_INFO:
            {
                PARKNTAPI pNtApiData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pNtApiData ) )
                {
                    if( STATUS_SUCCESS == InitNtApiData( pNtApiData ) )
                    {
                        retVal = STATUS_SUCCESS;
                        pIrp->IoStatus.Information = dwInBuffSize;
                    }
                }
            }
            break;

        case IOCTL_FIX_ISSUES:
            {
                PARKFIX pFixData = pIrp->AssociatedIrp.SystemBuffer;
                if( MmIsAddressValid( pFixData ) )
                {
                    switch( pFixData->eType )
                    {
                    case eArkKillProcess:
                        {
                            PDWORD pdwPid = (PDWORD)(pFixData->cFixData);
                            if( KillProcess( pdwPid ) )
                            {
                                retVal = STATUS_SUCCESS;
                            }
                        }
                        break;

                    case eArkFixSsdtHook:
                        {
                            PARKFIXSSDT pFixSsdtHookData = (PARKFIXSSDT)(pFixData->cFixData);
                            if( FixSSDTHook( pFixSsdtHookData ) )
                            {
                                retVal = STATUS_SUCCESS;
                            }
                        }
                        break;

                    case eArkFixInlineHook:
                        {
                            PARKFIXINLINEHOOK pFixInlineHook = (PARKFIXINLINEHOOK)(pFixData->cFixData);
                            if( FixInlineHook( pFixInlineHook ) )
                            {
                                retVal = STATUS_SUCCESS;
                            }
                        }
                        break;
                    }

                    if( STATUS_SUCCESS == retVal )
                    {
                        pIrp->IoStatus.Information = dwInBuffSize;
                    }
                }
            }
            break;

        default:
            {
                retVal = STATUS_UNSUCCESSFUL;
                pIrp->IoStatus.Information = 0;
            }
            break;
        }
        pIrp->IoStatus.Status = retVal;
        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    }
    __except( EXCEPTION_EXECUTE_HANDLER )
    {
        retVal = STATUS_UNSUCCESSFUL;
        DbgPrint( "Exception caught in DrvDispatch()" );
    }
    return retVal;
}