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
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
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
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
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
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
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
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
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
/** * 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