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

📄 usbprn.c

📁 cayman提供的PXA270 wince下的bsp源码包
💻 C
📖 第 1 页 / 共 3 页
字号:

   DEBUGMSG( ZONE_USB_INIT, (TEXT(">ParseUsbDescriptors\n")));

   if ( !hUsbDevice || !UsbFuncs || !CurInterface || !ConfigIndex) {
      DEBUGMSG( ZONE_ERR, (TEXT("Invalid parameter\n")));
      return NULL;
   }

   //
   // get the descriptors
   //
    pDevice = UsbFuncs->lpGetDeviceInfo( hUsbDevice );
   if ( !pDevice ) {
      DEBUGMSG( ZONE_ERR, (TEXT("GetDeviceInfo error:%d\n"), GetLastError() ));
      return NULL;
   }

   DUMP_USB_DEVICE_DESCRIPTOR( pDevice->Descriptor );
   DUMP_USB_CONFIGURATION_DESCRIPTOR( pDevice->lpActiveConfig->Descriptor );  

   // get config index
    for ( *ConfigIndex = 0; *ConfigIndex < (USHORT)pDevice->Descriptor.bNumConfigurations; *ConfigIndex++) {
        if (pDevice->lpActiveConfig == (pDevice->lpConfigs + *ConfigIndex)) {
            DEBUGMSG( ZONE_USB_INIT, (TEXT("ConfigIndex:%d\n"), *ConfigIndex));
         break;
      }
    }

    pUsbInterface   = pDevice->lpActiveConfig->lpInterfaces;
   dwNumInterfaces = pDevice->lpActiveConfig->dwNumInterfaces;

   // walk the interfaces searching for best fit
   for ( bProtocol = 0, dwIndex = 0; dwIndex < dwNumInterfaces; pUsbInterface++, dwIndex++) {

      DUMP_USB_INTERFACE_DESCRIPTOR( pUsbInterface->Descriptor, dwIndex );

        if ( pUsbInterface->Descriptor.bInterfaceNumber == CurInterface->Descriptor.bInterfaceNumber ) {
            if (pUsbInterface->Descriptor.bInterfaceClass     == USB_PRN_INTERFACE_CLASS &&
                pUsbInterface->Descriptor.bInterfaceSubClass  == USB_PRN_INTERFACE_SUBCLASS &&
                (pUsbInterface->Descriptor.bInterfaceProtocol == USB_PRN_INTERFACE_PROTOCOL_BI || 
                pUsbInterface->Descriptor.bInterfaceProtocol  == USB_PRN_INTERFACE_PROTOCOL_UNI) ) 
         {
            if (pUsbInterface->Descriptor.bInterfaceProtocol > bProtocol) {
                   pDesiredInterface = pUsbInterface;
                    bProtocol = pUsbInterface->Descriptor.bInterfaceProtocol;
               DEBUGMSG( ZONE_USB_INIT, (TEXT("*** Found interface @ index: %d ***\n"), dwIndex));
               }
            }
        }
    }
  
   DEBUGMSG( ZONE_USB_INIT, (TEXT("<ParseUsbDescriptors:0x%x\n"), pDesiredInterface ));

   return pDesiredInterface;
}


BOOL
SetUsbInterface(
   PUSBPRN_CONTEXT  pUsbPrn,
   LPCUSB_INTERFACE UsbInterface
   )
{
   USB_TRANSFER hTransfer;
   BOOL bRc = FALSE;
   DWORD dwIndex;

   DEBUGMSG( ZONE_USB_INIT, (TEXT(">SetUsbInterface\n")));

   if ( !VALID_CONTEXT( pUsbPrn ) || !UsbInterface ) {
      DEBUGMSG( ZONE_ERR, (TEXT("Invalid parameter\n")));
      return FALSE;
   }

   hTransfer = pUsbPrn->UsbFuncs->lpSetInterface( pUsbPrn->hUsbDevice,
                                                  NULL,
                                                  NULL,
                                                  0, // synchronous
                                                  UsbInterface->Descriptor.bInterfaceNumber,
                                                  UsbInterface->Descriptor.bAlternateSetting );

   if ( !hTransfer ) {
      DEBUGMSG( ZONE_ERR, (TEXT("SetUsbInterface error:%d\n"), GetLastError() ));
      return FALSE;
   }

   //
   // now parse the endpoints
   //
    for ( dwIndex = 0; dwIndex < UsbInterface->Descriptor.bNumEndpoints; dwIndex++) {
    
      LPCUSB_ENDPOINT pEndpoint;
      
      pEndpoint = UsbInterface->lpEndpoints + dwIndex;

      DUMP_USB_ENDPOINT_DESCRIPTOR(pEndpoint->Descriptor);

    // 
    // Printer Class supports 1 mandatory Bulk OUT and 1 optional Bulk IN
    // 
    if ( USB_ENDPOINT_DIRECTION_OUT( pEndpoint->Descriptor.bEndpointAddress ) ) {
            if ( NULL == pUsbPrn->BulkOut.hPipe  &&
              (pEndpoint->Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) {
               //
               // create the Bulk OUT pipe
               //
               pUsbPrn->BulkOut.hPipe = pUsbPrn->UsbFuncs->lpOpenPipe( pUsbPrn->hUsbDevice,
                                                                  &pEndpoint->Descriptor );
               if ( !pUsbPrn->BulkOut.hPipe ) {
                  DEBUGMSG( ZONE_ERR, (TEXT("OpenPipe error:%d\n"), GetLastError() ));
                  bRc = FALSE;
                  TEST_TRAP();
                  break;
               }

               //
               // setup any endpoint specific timers, buffers, context, etc.
               //
               pUsbPrn->BulkOut.hEvent = CreateEvent( NULL, MANUAL_RESET_EVENT, FALSE, NULL);
               if ( !pUsbPrn->BulkOut.hEvent ) {
                  DEBUGMSG( ZONE_ERR, (TEXT("CreateEvent error:%d\n"), GetLastError() ));
                  bRc = FALSE;
                  TEST_TRAP();
                  break;
               }

               pUsbPrn->BulkOut.bIndex = pEndpoint->Descriptor.bEndpointAddress;
         }

        } else if (USB_ENDPOINT_DIRECTION_IN( pEndpoint->Descriptor.bEndpointAddress ) ) {
         if ( NULL == pUsbPrn->BulkIn.hPipe && 
              USB_PRN_INTERFACE_PROTOCOL_BI == UsbInterface->Descriptor.bInterfaceProtocol &&
                  (pEndpoint->Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) {
               //
               // create the Bulk IN pipe
               //
               pUsbPrn->BulkIn.hPipe = pUsbPrn->UsbFuncs->lpOpenPipe( pUsbPrn->hUsbDevice,
                                                                 &pEndpoint->Descriptor );
               if ( !pUsbPrn->BulkIn.hPipe ) {
                  DEBUGMSG( ZONE_ERR, (TEXT("OpenPipe error: %d\n"), GetLastError() ));
                  bRc = FALSE;
                  TEST_TRAP();
                  break;
               }

               //
               // setup any endpoint specific timers, buffers, context, etc.
               //
               pUsbPrn->BulkIn.hEvent = CreateEvent( NULL, MANUAL_RESET_EVENT, FALSE, NULL);
               if ( !pUsbPrn->BulkIn.hEvent ) {
                  DEBUGMSG( ZONE_ERR, (TEXT("CreateEvent error:%d\n"), GetLastError() ));
                  bRc = FALSE;
                  TEST_TRAP();
                  break;
               }

               pUsbPrn->BulkIn.bIndex = pEndpoint->Descriptor.bEndpointAddress;
            }
        
      } else {
         DEBUGMSG( ZONE_WARN, (TEXT("Unsupported Endpoint:0x%x\n"), pEndpoint->Descriptor.bEndpointAddress));
      }
    }

   //
   // did we find our endpoints?
   //
    if ( USB_PRN_INTERFACE_PROTOCOL_UNI == UsbInterface->Descriptor.bInterfaceProtocol ) {
      
      bRc = pUsbPrn->BulkOut.hPipe ? TRUE : FALSE;
   
   } else {
      
      bRc = (pUsbPrn->BulkOut.hPipe && pUsbPrn->BulkIn.hPipe) ? TRUE : FALSE;
   }

   CloseTransferHandle(pUsbPrn->UsbFuncs, hTransfer);

   //
   // if we failed to find all of our endpoints then cleanup will occur later
   //

    DEBUGMSG( ZONE_USB_INIT, (TEXT("<SetUsbInterface:%d\n"), bRc));

    return (bRc);
}


BOOL WINAPI 
DeviceNotify(
   LPVOID lpvNotifyParameter,
   DWORD dwCode,
   LPDWORD * dwInfo1,
   LPDWORD * dwInfo2,
   LPDWORD * dwInfo3,
   LPDWORD * dwInfo4
   )
{
   PUSBPRN_CONTEXT pUsbPrn = (PUSBPRN_CONTEXT )lpvNotifyParameter;
   DWORD dwWaitReturn;
   BOOL bRc;

    UNREFERENCED_PARAMETER(dwInfo1);
    UNREFERENCED_PARAMETER(dwInfo2);
    UNREFERENCED_PARAMETER(dwInfo3);
    UNREFERENCED_PARAMETER(dwInfo4);

   DEBUGMSG( ZONE_USB_INIT, (TEXT(">DeviceNotify\n")));

   if ( !VALID_CONTEXT( pUsbPrn ) ) {
      DEBUGMSG( ZONE_ERR, (TEXT("Invalid Context!\n")));
      return FALSE;
   }
   
   switch(dwCode) {

      case USB_CLOSE_DEVICE:
        DEBUGMSG( ZONE_USB_INIT, (TEXT("USB_CLOSE_DEVICE\n")));
        if (pUsbPrn->Flags.Open) {
           //
           // When an app has an open handle to this device and then the user unplugs the USB cable
           // the driver will unload here. However, the app can a) hang on a removed handle, or
           // b) pass a call to a removed function, e.g., CloseHandle and cause an AV.
           // Set state to reject all I/O and wait for cleanup signal.
           //
           EnterCriticalSection( &pUsbPrn->Lock );
           pUsbPrn->Flags.Open = FALSE;
           pUsbPrn->Flags.UnloadPending = TRUE;
           LeaveCriticalSection( &pUsbPrn->Lock );

           DEBUGMSG( ZONE_USB_INIT, (TEXT("Waiting for CloseEvent...\n")));
           dwWaitReturn = WaitForSingleObject( pUsbPrn->hCloseEvent, INFINITE );

           switch (dwWaitReturn) {

               case WAIT_OBJECT_0:
                  DEBUGMSG( ZONE_USB_INIT, (TEXT("...CloseEvent signalled\n")));
                  break;

               case WAIT_FAILED:
                  DEBUGMSG( ZONE_ERR, (TEXT("CloseEvent error:%d\n"), GetLastError()));
                  TEST_TRAP();
                  break;
               
               default:
                  DEBUGMSG( ZONE_ERR, (TEXT("Unhandled WaitReason:%d\n"), dwWaitReturn ));
                  TEST_TRAP();
                  break;
            }
        
           //
           // Warning: DeactivateDevice forces Device Manager to call our LPT_Deinit, which then
           // causes COREDLL!xxX_CloseHandle to AV when PRNPORT!PrinterSend calls CloseHandle(hPrinter).
           // So, give it a chance to clean up.
           //
           Sleep(1000);
        }

        DEBUGMSG( ZONE_USB_INIT, (TEXT("DeactivateDevice\n")));

        bRc = DeactivateDevice( pUsbPrn->hStreamDevice );

        if ( !bRc ) {
            DEBUGMSG( ZONE_ERR, (TEXT("DeactivateDevice error: %d\n"), GetLastError() ));
            TEST_TRAP();
        }

        RemoveDeviceContext( pUsbPrn );

        return TRUE;

      default:
         DEBUGMSG( ZONE_ERR, (TEXT("Unhandled code:%d\n"), dwCode));
         TEST_TRAP();
         break;
    }
   
   DEBUGMSG( ZONE_USB_INIT, (TEXT("<DeviceNotify\n")));
   
   return FALSE;
}


/*++
Class specific command:
   GET_DEVICE_ID

Return: number of bytesin the Device ID string.
--*/
DWORD
GetDeviceId(
   PUSBPRN_CONTEXT pUsbPrn,
   PBYTE           pBuffer,
   DWORD           dwLen
   )
{
    USB_DEVICE_REQUEST ControlHeader;
    DWORD dwBytesTransferred = 0;
    DWORD dwErr = ERROR_SUCCESS;
    DWORD dwUsbErr = USB_NO_ERROR;

    DEBUGMSG( ZONE_USB_CONTROL, (TEXT(">GetDeviceId\n")));

    if ( !VALID_CONTEXT( pUsbPrn ) || !pBuffer || dwLen <= 2) {
        DEBUGMSG( ZONE_ERR, (TEXT("Invalid parameter\n")));
    } else {
   
        ControlHeader.bmRequestType = USB_REQUEST_DEVICE_TO_HOST | USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE;
        ControlHeader.bRequest = 0;
        ControlHeader.wValue = pUsbPrn->ConfigIndex;
        ControlHeader.wIndex = pUsbPrn->bInterfaceNumber*0x100 + pUsbPrn->bAlternateSetting;
        ControlHeader.wLength = (USHORT)dwLen;

        dwErr = IssueVendorTransfer( pUsbPrn->UsbFuncs,
                                     pUsbPrn->hUsbDevice,
                                     DefaultTransferComplete,
                                     pUsbPrn->hEP0Event,
                                     (USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK),
                                    &ControlHeader,
                                     pBuffer, 0,
                                    &dwBytesTransferred,
                                     pUsbPrn->UsbTimeouts.DeviceIdTimeout,
                                    &dwUsbErr );
      
      if ( ERROR_SUCCESS == dwErr && USB_NO_ERROR == dwUsbErr && dwBytesTransferred ) {
         //
         // remove the 2 byte IEEE-1284 Device ID string length for Port Monitor
         //
          if ( dwBytesTransferred > 2) {
              dwBytesTransferred -= 2;
              memmove( pBuffer, pBuffer + 2, dwBytesTransferred);
              pBuffer[dwBytesTransferred] = 0;
          } else {
              dwBytesTransferred = 0;
          };

      } else {
         DEBUGMSG( ZONE_ERR, (TEXT("IssueVendorTransfer ERROR:%d 0x%x\n"), dwErr, dwUsbErr));
         IoErrorHandler( pUsbPrn, NULL, 0, dwUsbErr);
      }
   }

    DEBUGMSG( ZONE_USB_CONTROL, (TEXT("<GetDeviceId:%d\n"), dwBytesTransferred));

   return dwBytesTransferred;
}


/*++
Class specific command:
   GET_PORT_STATUS

Return: printer status bits.
--*/
USHORT
GetPortStatus( 
   PUSBPRN_CONTEXT pUsbPrn
   )
{
    USB_DEVICE_REQUEST ControlHeader;
    DWORD  dwBytesTransferred = 0;
    DWORD  dwUsbErr = USB_NO_ERROR;
    DWORD  dwErr = ERROR_SUCCESS;

⌨️ 快捷键说明

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