Example #1
0
NTSTATUS INTERNAL
ReadReport(
    __in  PDEVICE_EXTENSION DevExt,
    __in  PIRP              Irp,
    __out BOOLEAN           *fSentDown
    )
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
    ULONG DataLen = irpsp->Parameters.DeviceIoControl.OutputBufferLength;

    TEnter(Func, ("(DevExt=%p,Irp=%p,IrpSp=%p)", DevExt, Irp, irpsp));
    TAssert(Irp->UserBuffer != NULL);
    if (DataLen != sizeof(HID_INPUT_REPORT))
    {
        status = STATUS_INVALID_BUFFER_SIZE;
        LogError(ERRLOG_INVALID_BUFFER_SIZE,
                 status,
                 UNIQUE_ERRID(0x60),
                 NULL,
                 NULL);
        TWarn(("Invalid input report size (len=%d,Expected=%d).",
               DataLen, sizeof(HID_INPUT_REPORT)));
    }
    else
    {
        status = OemReadReport(DevExt, Irp, fSentDown);
    }

    TExit(Func, ("=%x", status));
    return status;
}       //ReadReport
Example #2
0
NTSTATUS INTERNAL
GetAttributes(
    __in PDEVICE_EXTENSION DevExt,
    __in PIRP              Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  irpsp = NULL;

    UNREFERENCED_PARAMETER(DevExt);

    PAGED_CODE();

    irpsp = IoGetCurrentIrpStackLocation(Irp);

    TEnter(Func,("(DevExt=%p,Irp=%p,IrpSp=%p)\n", DevExt, Irp, irpsp));

    if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
        sizeof(HID_DEVICE_ATTRIBUTES))
    {
        status = STATUS_BUFFER_TOO_SMALL;
        LogError(ERRLOG_BUFFER_TOO_SMALL,
                 status,
                 UNIQUE_ERRID(0x90),
                 NULL,
                 NULL);
        TWarn(("output buffer too small (len=%d).\n",
                   irpsp->Parameters.DeviceIoControl.OutputBufferLength));
    }
    else
    {
        PHID_DEVICE_ATTRIBUTES DevAttrib;

        DevAttrib = (PHID_DEVICE_ATTRIBUTES)Irp->UserBuffer;

        DevAttrib->Size = sizeof(HID_DEVICE_ATTRIBUTES);
        DevAttrib->VendorID = OEM_VENDOR_ID;
        DevAttrib->ProductID = OEM_PRODUCT_ID;
        DevAttrib->VersionNumber = OEM_VERSION_NUM;

        Irp->IoStatus.Information = sizeof(HID_DEVICE_ATTRIBUTES);
        status = STATUS_SUCCESS;
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //GetAttributes
Example #3
0
NTSTATUS INTERNAL
GetReportDescriptor(
    __in PDEVICE_EXTENSION DevExt,
    __in PIRP              Irp
    )
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);

    
#ifdef _DBG
    TEnter(Func, ("(DevExt=%p,Irp=%p,IrpSp=%p)", DevExt, Irp, irpsp));
#else
    UNREFERENCED_PARAMETER(DevExt);
#endif

    PAGED_CODE ();

    if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
        gdwcbReportDescriptor)
    {
        status = STATUS_BUFFER_TOO_SMALL;
        LogError(ERRLOG_BUFFER_TOO_SMALL,
                 status,
                 UNIQUE_ERRID(0x50),
                 NULL,
                 NULL);
        TWarn(("Output buffer too small (len=%d).",
               irpsp->Parameters.DeviceIoControl.OutputBufferLength));
    }
    else
    {
        RtlCopyMemory(Irp->UserBuffer,
                      gReportDescriptor,
                      gdwcbReportDescriptor);

        Irp->IoStatus.Information = gdwcbReportDescriptor;
        status = STATUS_SUCCESS;
    }

#ifdef _DBG
    TExit(Func, ("=%x", status));
#endif
    return status;
}       //GetReportDescriptor
Example #4
0
NTSTATUS INTERNAL
GetDeviceDescriptor(
    __in PDEVICE_EXTENSION DevExt,
    __in PIRP              Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  irpsp = NULL;

    UNREFERENCED_PARAMETER(DevExt);
    PAGED_CODE ();

    irpsp = IoGetCurrentIrpStackLocation(Irp);

    TEnter(Func,("(DevExt=%p,Irp=%p,IrpSp=%p)\n", DevExt, Irp, irpsp));

    if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
        sizeof(gHidDescriptor))
    {
        status = STATUS_BUFFER_TOO_SMALL;
        LogError(ERRLOG_BUFFER_TOO_SMALL,
                 status,
                 UNIQUE_ERRID(0x40),
                 NULL,
                 NULL);
        TWarn(("output buffer too small (len=%d).\n",
                   irpsp->Parameters.DeviceIoControl.OutputBufferLength));
    }
    else
    {
        RtlCopyMemory(Irp->UserBuffer,
                      &gHidDescriptor,
                      sizeof(gHidDescriptor));

        Irp->IoStatus.Information = sizeof(gHidDescriptor);
        status = STATUS_SUCCESS;
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //GetDeviceDescriptor
Example #5
0
NTSTATUS INTERNAL
ReadReport(
    __in PDEVICE_EXTENSION DevExt,
    __in PIRP              Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  irpsp = NULL;

    irpsp = IoGetCurrentIrpStackLocation(Irp);

    TEnter(Func,("(DevExt=%p,Irp=%p,IrpSp=%p)\n", DevExt, Irp, irpsp));
    TAssert(Irp->UserBuffer != NULL);

    if (irpsp->Parameters.DeviceIoControl.OutputBufferLength !=
        sizeof(HID_INPUT_REPORT))
    {
        status = STATUS_INVALID_BUFFER_SIZE;
        LogError(ERRLOG_INVALID_BUFFER_SIZE,
                 status,
                 UNIQUE_ERRID(0x60),
                 NULL,
                 NULL);
        TWarn(("invalid input report size (len=%d).\n",
                   irpsp->Parameters.DeviceIoControl.OutputBufferLength));
    }
    else
    {
        IoCsqInsertIrp(&DevExt->IrpQueue,
                    Irp,
                    NULL);
        status = STATUS_PENDING;
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //ReadReport
Example #6
0
NTSTATUS EXTERNAL
HbtnInternalIoctl(
    IN PDEVICE_OBJECT DevObj,
    IN PIRP           Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION   devext = GET_MINIDRIVER_DEVICE_EXTENSION(DevObj);
    PIO_STACK_LOCATION  irpsp = IoGetCurrentIrpStackLocation(Irp);

    TEnter(Func,("(DevObj=%p,Irp=%p,IrpSp=%p,Ioctl=%s)\n",
                DevObj, Irp, irpsp,
                LookupName(irpsp->Parameters.DeviceIoControl.IoControlCode,
                           HidIoctlNames)));

    Irp->IoStatus.Information = 0;
    status = IoAcquireRemoveLock(&devext->RemoveLock, Irp);
    if (!NT_SUCCESS(status))
    {
        LogError(ERRLOG_DEVICE_REMOVED,
                 status,
                 UNIQUE_ERRID(0x10),
                 NULL,
                 NULL);
        TWarn(("received IRP after device was removed.\n"));
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }
    else if (!(devext->dwfHBtn & HBTNF_DEVICE_STARTED))
    {
        IoReleaseRemoveLock(&devext->RemoveLock, Irp);
        status = STATUS_DEVICE_NOT_READY;
        LogError(ERRLOG_DEVICE_NOT_STARTED,
                 status,
                 UNIQUE_ERRID(0x20),
                 NULL,
                 NULL);
        TWarn(("digitizer is not started.\n"));
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }
    else
    {
        switch(irpsp->Parameters.DeviceIoControl.IoControlCode)
        {
            case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
                status = GetDeviceDescriptor(devext, Irp);
                break;

            case IOCTL_HID_GET_REPORT_DESCRIPTOR:
                status = GetReportDescriptor(devext, Irp);
                break;

            case IOCTL_HID_READ_REPORT:
                status = ReadReport(devext, Irp);
                break;

            case IOCTL_HID_WRITE_REPORT:
                status = OemWriteReport(devext, Irp);
                break;

            case IOCTL_HID_GET_STRING:
                status = GetString(devext, Irp);
                break;

            case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
                status = GetAttributes(devext, Irp);
                break;

            case IOCTL_HID_ACTIVATE_DEVICE:
            case IOCTL_HID_DEACTIVATE_DEVICE:
                status = STATUS_SUCCESS;
                break;

            default:
                status = STATUS_NOT_SUPPORTED;
                LogError(ERRLOG_NOT_SUPPORTED,
                         status,
                         UNIQUE_ERRID(0x30),
                         NULL,
                         NULL);
                TWarn(("unsupported (IOCTL=%x).\n",
                           irpsp->Parameters.DeviceIoControl.IoControlCode));
                break;
        }

        if (status != STATUS_PENDING)
        {
            IoReleaseRemoveLock(&devext->RemoveLock, Irp);
            Irp->IoStatus.Status = status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }
        else
        {
            IoMarkIrpPending(Irp);
        }
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //HbtnInternalIoctl
Example #7
0
NTSTATUS INTERNAL
GetString(
    __in PDEVICE_EXTENSION DevExt,
    __in PIRP              Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  irpsp = NULL;
    PWSTR               pwstrID = NULL;
    ULONG_PTR           lenID = 0;
    ULONG_PTR           ulpStringID = 0;

    UNREFERENCED_PARAMETER(DevExt);

    PAGED_CODE();

    irpsp = IoGetCurrentIrpStackLocation(Irp);

    ulpStringID = (ULONG_PTR)(irpsp->Parameters.DeviceIoControl.Type3InputBuffer);
    TEnter(Func,("(DevExt=%p,Irp=%p,IrpSp=%p,StringID=%x)\n",
                DevExt, Irp, irpsp,
                (unsigned int)ulpStringID));

    switch (0xFFFF & ulpStringID)
    {
        case HID_STRING_ID_IMANUFACTURER:
            pwstrID = gpwstrManufacturerID;
            break;

        case HID_STRING_ID_IPRODUCT:
            pwstrID = gpwstrProductID;
            break;

        case HID_STRING_ID_ISERIALNUMBER:
            pwstrID = gpwstrSerialNumber;
            break;

        default:
            pwstrID = NULL;
            break;
    }

    lenID = pwstrID? wcslen(pwstrID)*sizeof(WCHAR) + sizeof(UNICODE_NULL): 0;
    if (pwstrID == NULL)
    {
        status = STATUS_INVALID_PARAMETER;
        LogError(ERRLOG_INVALID_PARAMETER,
                 status,
                 UNIQUE_ERRID(0x70),
                 NULL,
                 NULL);
        TWarn(("invalid string ID (ID=%x).\n",
                   (unsigned int)ulpStringID));
    }
    else if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < lenID)
    {
        status = STATUS_BUFFER_TOO_SMALL;
        LogError(ERRLOG_BUFFER_TOO_SMALL,
                 status,
                 UNIQUE_ERRID(0x80),
                 NULL,
                 NULL);
        TWarn(("output buffer too small (len=%d,need=%d).\n",
                   irpsp->Parameters.DeviceIoControl.OutputBufferLength,
                   (LONG)lenID));
    }
    else
    {
        RtlCopyMemory(Irp->UserBuffer, pwstrID, lenID);

        Irp->IoStatus.Information = lenID;
        status = STATUS_SUCCESS;
    }

    TExit(Func,("=%x (string=%S)\n", status, pwstrID? pwstrID: L"Null"));
    return status;
}       //GetString
Example #8
0
VOID
LogError(
    IN NTSTATUS ErrorCode,
    IN NTSTATUS NTStatus,
    IN ULONG    UniqueID OPTIONAL,
    IN PCWSTR   String1  OPTIONAL,
    IN PCWSTR   String2  OPTIONAL
    )
{
    TEnter(Func, ("(ErrorCode=%x,NTStatus=%x,UniqueID=%x,Str1=%S,Str2=%S)",
                  ErrorCode, NTStatus, UniqueID, String1? String1: L"",
                  String2? String2: L""));

    TAssert(gDriverObj != NULL);
    if (gDriverObj != NULL)
    {
        ULONG_PTR len1, len2, len;
        PIO_ERROR_LOG_PACKET ErrEntry;

        len1 = String1? (wcslen(String1) + 1)*sizeof(WCHAR): 0;
        len2 = String2? (wcslen(String2) + 1)*sizeof(WCHAR): 0;
        len = len1 + len2 + FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData);
        len = max(len, sizeof(IO_ERROR_LOG_PACKET));
        // Thoroughly check the value of len to prevent buffer underflows/overflows
        if ((len > 0) && (len <= 255) && (len1 <= len) && (len2 <= len))
        {
            ErrEntry = IoAllocateErrorLogEntry(gDriverObj, (UCHAR)len);
            if (ErrEntry)
            {
                PUCHAR pbBuff = (PUCHAR)ErrEntry +
                                        FIELD_OFFSET(IO_ERROR_LOG_PACKET,
                                                     DumpData);

                ErrEntry->NumberOfStrings = 0;
                if (len1 > 0)
                {
                    ErrEntry->NumberOfStrings++;
                    RtlCopyMemory(pbBuff, String1, len1);
                    pbBuff += len1;
                }
                if (len2 > 0)
                {
                    ErrEntry->NumberOfStrings++;
                    RtlCopyMemory(pbBuff, String2, len2);
                    pbBuff += len2;
                }
                ErrEntry->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET,
                                                      DumpData);

                ErrEntry->ErrorCode = ErrorCode;
                ErrEntry->FinalStatus = NTStatus;
                ErrEntry->UniqueErrorValue = UniqueID;
                IoWriteErrorLogEntry(ErrEntry);
            }
            else
            {
                TWarn(("Failed to allocate error log entry (len=%d).", (int)len));
            }
        }
        else
        {
            TWarn(("Error log entry too big (len=%d).", (int)len));
        }
    }

    TExit(Func, ("!"));
    return;
}       //LogError
Example #9
0
VOID __cdecl
LogDbgMsg(
    IN NTSTATUS ErrorCode,
    IN NTSTATUS NTStatus OPTIONAL,
    _In_z_ LPCSTR pszFormat,
    ...
    )
{
    #define MAX_ERRMSG_LEN      ((ERROR_LOG_MAXIMUM_SIZE -                     \
                                  FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData)) \
                                 /sizeof(WCHAR))
    static char szErrMsg[MAX_ERRMSG_LEN] = {0};

    TEnter(Func, ("(ErrorCode=%x,NTStatus=%x,Format=%s)",
                  ErrorCode, NTStatus, pszFormat));

    TAssert(gDriverObj != NULL);
    if (gDriverObj != NULL)
    {
        va_list arglist;
        NTSTATUS status;
        size_t iLen = 0;
        ULONG_PTR iTotalLen;
        PIO_ERROR_LOG_PACKET ErrEntry;

        va_start(arglist, pszFormat);
        status = RtlStringCchVPrintfA(szErrMsg,
                               ARRAYSIZE(szErrMsg),
                               pszFormat,
                               arglist);
        va_end(arglist);
        if (NT_SUCCESS(status))
        {
            status = RtlStringCchLengthA(szErrMsg, ARRAYSIZE(szErrMsg), &iLen);
        }

        if (NT_SUCCESS(status))
        {
            iTotalLen = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) +
                        (iLen + 1)*sizeof(WCHAR);
            iTotalLen = max(iTotalLen, sizeof(IO_ERROR_LOG_PACKET));
            ErrEntry = IoAllocateErrorLogEntry(gDriverObj, (UCHAR)iTotalLen);
            if (ErrEntry)
            {
                ErrEntry->NumberOfStrings = 1;
                ErrEntry->ErrorCode = ErrorCode;
                ErrEntry->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET,
                                                      DumpData);
                mbstowcs((WCHAR *)ErrEntry->DumpData, szErrMsg, iLen);
                ErrEntry->FinalStatus = NTStatus;
                IoWriteErrorLogEntry(ErrEntry);
            }
            else
            {
                TWarn(("Failed to allocate error log entry (len=%d).",
                       (int)iTotalLen));
            }

            if (ErrorCode == ERRLOG_DEBUG_INFORMATION)
            {
                TInfo(("%s", szErrMsg));
            }
            else if (ErrorCode == ERRLOG_DEBUG_WARNING)
            {
                TWarn(("%s", szErrMsg));
            }
            else if (ErrorCode == ERRLOG_DEBUG_ERROR)
            {
                TErr(("%s", szErrMsg));
            }
        }
    }

    TExit(Func, ("!"));
    return;
}       //LogDbgMsg
Example #10
0
/**
 *  This function reads the configuration from the registry if it exists.
 *  It is not an error if it doesn't exist. We will just use the default
 *  values.
 *
 *  @param configParams Points to the CONFIG_PARAMS structure to be filled
 *         in.
 *
 *  @return Success: Returns S_OK.
 *  @return Failure: Returns HRESULT_CODE.
 */
HRESULT
RegistryGetConfig(
    __inout PCONFIG_PARAMS configParams
    )
{
    HRESULT hr;
    LONG rcReg;
    HKEY hkey;

    TLevel(FUNC);
    TEnterMsg(("configParams=%p", configParams));

    rcReg = RegOpenKeyW(HKEY_CURRENT_USER, REGSTR_PATH_NETTERM, &hkey);
    if (rcReg != ERROR_SUCCESS)
    {
        //
        // It's okay to fail. It could just mean we did not save the config
        // in the registry.
        //
        TWarn(("Failed to open registry key <%ws> (rc=%d).",
               REGSTR_PATH_NETTERM, rcReg));
        rcReg = ERROR_SUCCESS;
    }
    else
    {
        DWORD dwType;
        DWORD dwSize;

        dwSize = sizeof(configParams->szRemoteAddr);
        if ((rcReg = RegQueryValueExW(hkey,
                                      REGSTR_VALUE_REMOTEADDR,
                                      NULL,
                                      &dwType,
                                      (LPBYTE)configParams->szRemoteAddr,
                                      &dwSize)) != ERROR_SUCCESS)
        {
            //
            // It's okay if the value doesn't exist.
            //
            TWarn(("Failed to get remote address from registry (rc=%d).",
                   rcReg));
            rcReg = ERROR_SUCCESS;
        }
        else if (dwType != REG_SZ)
        {
            rcReg = ERROR_INVALID_DATA;
            MsgPrintf(g_progName, MSGTYPE_ERR, rcReg,
                      L"Invalid remote IP address.");
        }

        if (rcReg == ERROR_SUCCESS)
        {
            dwSize = sizeof(configParams->szRemotePort);
            if ((rcReg = RegQueryValueExW(hkey,
                                          REGSTR_VALUE_REMOTEPORT,
                                          NULL,
                                          &dwType,
                                          (LPBYTE)configParams->szRemotePort,
                                          &dwSize)) != ERROR_SUCCESS)
            {
                //
                // It's okay if the value doesn't exist.
                //
                TWarn(("Failed to get remote port from registry (rc=%d).",
                       rcReg));
                rcReg = ERROR_SUCCESS;
            }
            else if (dwType != REG_SZ)
            {
                rcReg = ERROR_INVALID_DATA;
                MsgPrintf(g_progName, MSGTYPE_ERR, rcReg,
                          L"Invalid remote port.");
            }
        }

        if (rcReg == ERROR_SUCCESS)
        {
            dwSize = sizeof(configParams->szLocalPort);
            if ((rcReg = RegQueryValueExW(hkey,
                                          REGSTR_VALUE_LOCALPORT,
                                          NULL,
                                          &dwType,
                                          (LPBYTE)configParams->szLocalPort,
                                          &dwSize)) != ERROR_SUCCESS)
            {
                //
                // It's okay if the value doesn't exist.
                //
                TWarn(("Failed to get local port from registry (rc=%d).",
                       rcReg));
                rcReg = ERROR_SUCCESS;
            }
            else if (dwType != REG_SZ)
            {
                rcReg = ERROR_INVALID_DATA;
                MsgPrintf(g_progName, MSGTYPE_ERR, rcReg,
                          L"Invalid local port.");
            }
        }

        RegCloseKey(hkey);
    }

    hr = HRESULT_FROM_WIN32(rcReg);

    TExitMsg(("=%x (remoteAddr=%ws,remotePort=%ws,localPort=%ws)",
              hr, configParams->szRemoteAddr, configParams->szRemotePort,
              configParams->szLocalPort));
    return hr;
}   //RegistryGetConfig