ForUsbDevice.cpp
上传用户:lyfy_2008
上传日期:2014-07-13
资源大小:3016k
文件大小:29k
源码类别:

USB编程

开发平台:

Visual C++

  1. // ForUsbDevice.cpp
  2. // Implementation of ForUsbDevice device class
  3. //
  4. // Generated by DriverWizard version DriverStudio 2.7.0 (Build 562)
  5. // Requires Compuware's DriverWorks classes
  6. //
  7. #pragma warning(disable:4065) // Allow switch statement with no cases
  8.   
  9. #include <vdw.h>
  10. #include <kusb.h>
  11. #include "..commonForUsbDeviceinterface.h"
  12. #include "ForUsb.h"
  13. #include "ForUsbDevice.h"
  14. #include "..commonForUsbioctl.h"
  15. #pragma hdrstop("ForUsb.pch")
  16. extern KTrace t; // Global driver trace object
  17. GUID ForUsbDevice_Guid = ForUsbDevice_CLASS_GUID;
  18. ////////////////////////////////////////////////////////////////////////
  19. //  ForUsbDevice::ForUsbDevice
  20. //
  21. // Routine Description:
  22. // This is the constructor for the Functional Device Object, or FDO.
  23. // It is derived from KPnpDevice, which builds in automatic
  24. //     dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to
  25. // virtual member functions.
  26. //
  27. // Parameters:
  28. // Pdo - Physical Device Object - this is a pointer to a system
  29. // device object that represents the physical device.
  30. //
  31. // Unit - Unit number. This is a number to append to the device's
  32. // base device name to form the Logical Device Object's name
  33. //
  34. // Return Value:
  35. // None   
  36. //
  37. // Comments:
  38. // The object being constructed contains a data member (m_Lower) of type
  39. // KPnpLowerDevice. By initializing it, the driver binds the FDO to the
  40. // PDO and creates an interface to the upper edge of the system class driver.
  41. //
  42. ForUsbDevice::ForUsbDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
  43. KPnpDevice(Pdo, &ForUsbDevice_Guid)
  44. {
  45. t << "Entering ForUsbDevice::ForUsbDevice (constructor)n";
  46. // Check constructor status
  47.     if ( ! NT_SUCCESS(m_ConstructorStatus) )
  48. {
  49.     return;
  50. }
  51. // Remember our unit number
  52. m_Unit = Unit;
  53. // Initialize the lower device
  54. m_Lower.Initialize(this, Pdo);
  55. // Initialize the interface object.  The wizard generates code 
  56. // to support a single interface.  You may create and add additional 
  57. // interfaces.  By default, the wizard uses InterfaceNumber 0 (the 
  58. // first interface descriptor), ConfigurationValue 1 (the first
  59. // configuration descriptor), and initial interface alternate
  60. // setting of 0.  If your device has multiple interfaces or alternate
  61. // settings for an interface, you can add additional KUsbInterface
  62. // objects or adjust the parameters passed to this function.
  63. m_Interface.Initialize(
  64. m_Lower, //KUsbLowerDevice
  65. 0,  //InterfaceNumber
  66. 1,  //ConfigurationValue 
  67. 0  //Initial Interface Alternate Setting
  68. ); 
  69. // Initialize each Pipe object
  70. m_Endpoint1IN.Initialize(m_Lower, 0x81, 16); 
  71. m_Endpoint1OUT.Initialize(m_Lower, 0x1, 16); 
  72. m_Endpoint2IN.Initialize(m_Lower, 0x82, 64); 
  73. m_Endpoint2OUT.Initialize(m_Lower, 0x2, 64); 
  74.     // Inform the base class of the lower edge device object
  75. SetLowerDevice(&m_Lower);
  76. // Initialize the PnP Policy settings to the "standard" policy
  77. SetPnpPolicy();
  78. // TODO: Customize the PnP Policy for this device by setting
  79. // flags in m_Policies.
  80. // Initialize the Power Policy settings to the "standard" policy
  81. SetPowerPolicy();
  82. // TODO: Customize the Power Policy for this device by setting
  83. // flags in m_PowerPolicies.
  84. }
  85. ////////////////////////////////////////////////////////////////////////
  86. //  ForUsbDevice::~ForUsbDevice
  87. //
  88. // Routine Description:
  89. // This is the destructor for the Functional Device Object, or FDO.
  90. //
  91. // Parameters:
  92. // None
  93. //
  94. // Return Value:
  95. // None
  96. //
  97. // Comments:
  98. // None
  99. //
  100. ForUsbDevice::~ForUsbDevice()
  101. {
  102. t << "Entering ForUsbDevice::~ForUsbDevice() (destructor)n";
  103. }
  104. ////////////////////////////////////////////////////////////////////////
  105. //  PNPMinorFunctionName
  106. //
  107. // Routine Description:
  108. // Return a string describing the Plug and Play minor function
  109. //
  110. // Parameters:
  111. // mn - Minor function code
  112. //
  113. // Return Value:
  114. // char * - Ascii name of minor function
  115. //
  116. // Comments:
  117. // This function is used for tracing the IRPs.  Remove the function,
  118. // or conditionalize it for debug-only builds, if you want to save
  119. // space in the driver image.
  120. //
  121. char *PNPMinorFunctionName(ULONG mn)
  122. {
  123. static char* minors[] = {
  124. "IRP_MN_START_DEVICE",
  125. "IRP_MN_QUERY_REMOVE_DEVICE",
  126. "IRP_MN_REMOVE_DEVICE",
  127. "IRP_MN_CANCEL_REMOVE_DEVICE",
  128. "IRP_MN_STOP_DEVICE",
  129. "IRP_MN_QUERY_STOP_DEVICE",
  130. "IRP_MN_CANCEL_STOP_DEVICE",
  131. "IRP_MN_QUERY_DEVICE_RELATIONS",
  132. "IRP_MN_QUERY_INTERFACE",
  133. "IRP_MN_QUERY_CAPABILITIES",
  134. "IRP_MN_QUERY_RESOURCES",
  135. "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
  136. "IRP_MN_QUERY_DEVICE_TEXT",
  137. "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
  138. "<unknown minor function>",
  139. "IRP_MN_READ_CONFIG",
  140. "IRP_MN_WRITE_CONFIG",
  141. "IRP_MN_EJECT",
  142. "IRP_MN_SET_LOCK",
  143. "IRP_MN_QUERY_ID",
  144. "IRP_MN_QUERY_PNP_DEVICE_STATE",
  145. "IRP_MN_QUERY_BUS_INFORMATION",
  146. "IRP_MN_DEVICE_USAGE_NOTIFICATION",
  147. "IRP_MN_SURPRISE_REMOVAL",
  148. "IRP_MN_QUERY_LEGACY_BUS_INFORMATION"
  149. };
  150. if (mn > 0x18) // IRP_MN_QUERY_LEGACY_BUS_INFORMATION
  151. return "<unknown minor function>";
  152. else
  153. return minors[mn];
  154. }
  155. ////////////////////////////////////////////////////////////////////////
  156. //  ForUsbDevice::DefaultPnp
  157. //
  158. // Routine Description:
  159. // Default handler for IRP_MJ_PNP
  160. //
  161. // Parameters:
  162. // I - Current IRP
  163. //
  164. // Return Value:
  165. // NTSTATUS - Result returned from lower device
  166. //
  167. // Comments:
  168. // This routine just passes the IRP through to the lower device. It is 
  169. // the default handler for IRP_MJ_PNP. IRPs that correspond to
  170. // any virtual members of KpnpDevice that handle minor functions of
  171. // IRP_MJ_PNP and that are not overridden get passed to this routine.
  172. //
  173. NTSTATUS ForUsbDevice::DefaultPnp(KIrp I) 
  174. {
  175. t << "Entering ForUsbDevice::DefaultPnp with IRP minor function="
  176.   << PNPMinorFunctionName(I.MinorFunction()) << EOL;
  177. I.ForceReuseOfCurrentStackLocationInCalldown();
  178. return m_Lower.PnpCall(this, I);
  179. }
  180. ////////////////////////////////////////////////////////////////////////
  181. //  ForUsbDevice::DefaultPower
  182. //
  183. // Routine Description:
  184. // Default handler for IRP_MJ_POWER 
  185. //
  186. // Parameters:
  187. // I - Current IRP
  188. //
  189. // Return Value:
  190. // NTSTATUS - Result returned from lower device
  191. //
  192. // Comments:
  193. // This routine just passes the IRP through to the lower device. It is 
  194. // the default handler for IRP_MJ_POWER.
  195. //
  196. NTSTATUS ForUsbDevice::DefaultPower(KIrp I) 
  197. {
  198. t << "Entering ForUsbDevice::DefaultPowern";
  199. I.IndicatePowerIrpProcessed();
  200. I.CopyParametersDown();
  201. return m_Lower.PnpPowerCall(this, I);
  202. }
  203. ////////////////////////////////////////////////////////////////////////////////
  204. //  ForUsbDevice::SystemControl
  205. //
  206. // Routine Description:
  207. // Default handler for IRP_MJ_SYSTEM_CONTROL
  208. //
  209. // Parameters:
  210. // I - Current IRP
  211. //
  212. // Return Value:
  213. // NTSTATUS - Result returned from lower device
  214. //
  215. // Comments:
  216. // This routine just passes the IRP through to the next device since this driver
  217. // is not a WMI provider.
  218. //
  219. NTSTATUS ForUsbDevice::SystemControl(KIrp I) 
  220. {
  221. t << "Entering ForUsbDevice::SystemControln";
  222. I.ForceReuseOfCurrentStackLocationInCalldown();
  223. return m_Lower.PnpCall(this, I);
  224. }
  225. ////////////////////////////////////////////////////////////////////////
  226. //  ForUsbDevice::OnStartDevice
  227. //
  228. // Routine Description:
  229. // Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE
  230. //
  231. // Parameters:
  232. // I - Current IRP
  233. //
  234. // Return Value:
  235. // NTSTATUS - Result code
  236. //
  237. // Comments:
  238. // Typically, the driver sends a SET CONFIGURATION request for the
  239. // USB device by using KUsbLowerDevice::ActivateConfiguration with
  240. // the ConfigurationValue to activate.  The wizard generates code to 
  241. // support a single configuration.  You may create and add additional 
  242. // configurations. 
  243. //
  244. NTSTATUS ForUsbDevice::OnStartDevice(KIrp I)
  245. {
  246. t << "Entering ForUsbDevice::OnStartDevicen";
  247. NTSTATUS status = STATUS_UNSUCCESSFUL;
  248. AC_STATUS acStatus = AC_SUCCESS;
  249. I.Information() = 0;
  250. // The default Pnp policy has already cleared the IRP with the lower device
  251. //By default, the wizard passes a ConfigurationValue of 1 to 
  252. //ActivateConfiguration().  This corresponds to the first configuration 
  253. //that the device reports in its configuration descriptor.  If the device 
  254. //supports multiple configurations, pass the appropriate
  255. //ConfigurationValue of the configuration to activate here.
  256. acStatus = m_Lower.ActivateConfiguration(
  257. 1 // ConfigurationValue 1 (the first configuration)
  258. );
  259. switch (acStatus)
  260. {
  261. case AC_SUCCESS:
  262. t << "USB Configuration OKn";
  263. status = STATUS_SUCCESS;
  264. break;
  265. case AC_COULD_NOT_LOCATE_INTERFACE:
  266. t << "Could not locate interfacen";
  267. break;
  268. case AC_COULD_NOT_PRECONFIGURE_INTERFACE:
  269. t << "Could not get configuration descriptorn";
  270. break;
  271. case AC_CONFIGURATION_REQUEST_FAILED:
  272. t << "Board did not accept configuration URBn";
  273. break;
  274. case AC_FAILED_TO_INITIALIZE_INTERFACE_OBJECT:
  275. t << "Failed to initialize interface objectn";
  276. break;
  277. case AC_FAILED_TO_GET_DESCRIPTOR:
  278. t << "Failed to get device descriptorn";
  279. break;
  280. case AC_FAILED_TO_OPEN_PIPE_OBJECT:
  281. //NOTE: this may not be an error.  It could mean that
  282. //the device has an endpoint for which a KUsbPipe object has
  283. //not been instanced.  If the intention is to not use this endpoint,
  284. //then it's likely not a problem.  
  285. status = STATUS_SUCCESS;
  286. t << "Failed to open pipe objectn";
  287. break;
  288. default:
  289. t << "Unexpected error activating USB configurationn";
  290. break;
  291. }
  292.    return status;  // base class completes the IRP
  293. }
  294. ////////////////////////////////////////////////////////////////////////
  295. //  ForUsbDevice::OnStopDevice
  296. //
  297. // Routine Description:
  298. // Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE
  299. //
  300. // Parameters:
  301. // I - Current IRP
  302. //
  303. // Return Value:
  304. // NTSTATUS - Result code
  305. //
  306. // Comments:
  307. // The system calls this when the device is stopped.
  308. // The driver should release any hardware resources
  309. // in this routine.
  310. //
  311. // The base class passes the irp to the lower device.
  312. //
  313. NTSTATUS ForUsbDevice::OnStopDevice(KIrp I)
  314. {
  315. NTSTATUS status = STATUS_SUCCESS;
  316. t << "Entering ForUsbDevice::OnStopDevicen";
  317. m_Lower.DeActivateConfiguration();
  318. // TODO: Add device-specific code to stop your device   
  319. return status;
  320. // The following macro simply allows compilation at Warning Level 4
  321. // If you reference this parameter in the function simply remove the macro.
  322. UNREFERENCED_PARAMETER(I);
  323. }
  324. ////////////////////////////////////////////////////////////////////////
  325. //  ForUsbDevice::OnRemoveDevice
  326. //
  327. // Routine Description:
  328. // Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE
  329. //
  330. // Parameters:
  331. // I - Current IRP
  332. //
  333. // Return Value:
  334. // NTSTATUS - Result code
  335. //
  336. // Comments:
  337. // The system calls this when the device is removed.
  338. // Our PnP policy will take care of 
  339. // (1) giving the IRP to the lower device
  340. // (2) detaching the PDO
  341. // (3) deleting the device object
  342. //
  343. NTSTATUS ForUsbDevice::OnRemoveDevice(KIrp I)
  344. {
  345. t << "Entering ForUsbDevice::OnRemoveDevicen";
  346. // Device removed, release the system resources used by the USB lower device.
  347. m_Lower.ReleaseResources();
  348. // TODO: Add device-specific code to remove your device   
  349. return STATUS_SUCCESS;
  350. // The following macro simply allows compilation at Warning Level 4
  351. // If you reference this parameter in the function simply remove the macro.
  352. UNREFERENCED_PARAMETER(I);
  353. }
  354. ////////////////////////////////////////////////////////////////////////
  355. //  ForUsbDevice::OnDevicePowerUp
  356. //
  357. // Routine Description:
  358. // Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
  359. // for a request to go to power on state from low power state
  360. //
  361. // Parameters:
  362. // I - IRP containing POWER request
  363. //
  364. // Return Value:
  365. // NTSTATUS - Status code indicating success or failure
  366. //
  367. // Comments:
  368. // This routine implements the OnDevicePowerUp function.
  369. // This function was called by the framework from the completion
  370. // routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
  371. // The bus driver has completed the IRP and this driver can now
  372. // access the hardware device.  
  373. // This routine runs at dispatch level.
  374. //
  375. NTSTATUS ForUsbDevice::OnDevicePowerUp(KIrp I)
  376. {
  377. NTSTATUS status = STATUS_SUCCESS;
  378. t << "Entering ForUsbDevice::OnDevicePowerUpn";
  379. // TODO: Service the device.
  380. // Restore any context to the hardware device that
  381. // was saved during the handling of a power down request.
  382. // See the OnDeviceSleep function.
  383. // Do NOT complete this IRP.
  384. //
  385. return status;
  386. // The following macro simply allows compilation at Warning Level 4
  387. // If you reference this parameter in the function simply remove the macro.
  388. UNREFERENCED_PARAMETER(I);
  389. }
  390. ////////////////////////////////////////////////////////////////////////
  391. //  ForUsbDevice::OnDeviceSleep
  392. //
  393. // Routine Description:
  394. // Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
  395. // for a request to go to a low power state from a high power state
  396. //
  397. // Parameters:
  398. // I - IRP containing POWER request
  399. //
  400. // Return Value:
  401. // NTSTATUS - Status code indicating success or failure
  402. //
  403. // Comments:
  404. // This routine implements the OnDeviceSleep function.
  405. // This function was called by the framework from the IRP_MJ_POWER 
  406. // dispatch handler in KPnpDevice prior to forwarding to the PDO.
  407. // The hardware has yet to be powered down and this driver can now
  408. // access the hardware device.  
  409. // This routine runs at passive level.
  410. //
  411. NTSTATUS ForUsbDevice::OnDeviceSleep(KIrp I)
  412. {
  413. NTSTATUS status = STATUS_SUCCESS;
  414. t << "Entering ForUsbDevice::OnDeviceSleepn";
  415. // TODO: Service the device.
  416. // Save any context to the hardware device that will be required 
  417. // during a power up request. See the OnDevicePowerUp function.
  418. // Do NOT complete this IRP.  The base class handles forwarding
  419. // this IRP to the PDO.
  420. //
  421. return status;
  422. // The following macro simply allows compilation at Warning Level 4
  423. // If you reference this parameter in the function simply remove the macro.
  424. UNREFERENCED_PARAMETER(I);
  425. }
  426. ////////////////////////////////////////////////////////////////////////
  427. //  ForUsbDevice::Create
  428. //
  429. // Routine Description:
  430. // Handler for IRP_MJ_CREATE
  431. //
  432. // Parameters:
  433. // I - Current IRP
  434. //
  435. // Return Value:
  436. // NTSTATUS - Result code
  437. //
  438. // Comments:
  439. //
  440. NTSTATUS ForUsbDevice::Create(KIrp I)
  441. {
  442. NTSTATUS status;
  443. t << "Entering ForUsbDevice::Create, " << I << EOL;
  444. // TODO: Add driver specific create handling code here
  445. // Generally a create IRP is targeted at our FDO, so we don't need
  446. // to pass it down to the PDO.  We have found for some devices, the
  447. // PDO is not expecting this Irp and returns an error code.
  448. // The default wizard code, therefore completes the Irp here using
  449. // PnpComplete().  The following commented code could be used instead
  450. // of PnpComplete() to pass the Irp to the PDO, which would complete it.
  451. //
  452. // I.ForceReuseOfCurrentStackLocationInCalldown();
  453. // status = m_Lower.PnpCall(this, I);
  454. status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
  455. t << "ForUsbDevice::Create Status " << (ULONG)status << EOL;
  456. return status;
  457. }
  458. ////////////////////////////////////////////////////////////////////////
  459. //  ForUsbDevice::Close
  460. //
  461. // Routine Description:
  462. // Handler for IRP_MJ_CLOSE
  463. //
  464. // Parameters:
  465. // I - Current IRP
  466. //
  467. // Return Value:
  468. // NTSTATUS - Result code
  469. //
  470. // Comments:
  471. //
  472. NTSTATUS ForUsbDevice::Close(KIrp I)
  473. {
  474. NTSTATUS status;
  475. t << "Entering ForUsbDevice::Close, " << I << EOL;
  476. // TODO: Add driver specific close handling code here
  477. // Generally a close IRP is targeted at our FDO, so we don't need
  478. // to pass it down to the PDO.  We have found for some devices, the
  479. // PDO is not expecting this Irp and returns an error code.
  480. // The default wizard code, therefore completes the Irp here using
  481. // PnpComplete().  The following commented code could be used instead
  482. // of PnpComplete() to pass the Irp to the PDO, which would complete it.
  483. //
  484. // I.ForceReuseOfCurrentStackLocationInCalldown();
  485. // status = m_Lower.PnpCall(this, I);
  486. status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
  487. t << "ForUsbDevice::Close Status " << (ULONG)status << EOL;
  488.     return status;
  489. }
  490. ////////////////////////////////////////////////////////////////////////
  491. //  ForUsbDevice::Cleanup
  492. //
  493. // Routine Description:
  494. // Handler for IRP_MJ_CLEANUP
  495. //
  496. // Parameters:
  497. // I - Current IRP
  498. //
  499. // Return Value:
  500. // NTSTATUS - Result code
  501. //
  502. // Comments:
  503. //
  504. NTSTATUS ForUsbDevice::CleanUp(KIrp I)
  505. {
  506. t << "Entering CleanUp, " << I << EOL;
  507. // TODO: Insert your code to respond to the CLEANUP message.
  508. return I.PnpComplete(this, STATUS_SUCCESS);
  509. }
  510. ////////////////////////////////////////////////////////////////////////
  511. //  ForUsbDevice::Read
  512. //
  513. // Routine Description:
  514. // Handler for IRP_MJ_READ
  515. //
  516. // Parameters:
  517. // I Current IRP
  518. //
  519. // Return Value:
  520. // NTSTATUS Result code
  521. //
  522. // Comments:
  523. // This routine handles read requests.
  524. //
  525. // The KPnpDevice class handles restricting IRP flow
  526. // if the device is stopping or being removed.
  527. //
  528. NTSTATUS ForUsbDevice::Read(KIrp I) 
  529. {
  530. t << "Entering ForUsbDevice::Read, " << I << EOL;
  531. // TODO: Check the incoming request.  Replace "FALSE" in the following
  532. // line with a check that returns TRUE if the request is not valid.
  533.     if (FALSE) // If (Request is invalid)
  534. {
  535. // Invalid parameter in the Read request
  536. I.Information() = 0;
  537. return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
  538. }
  539. // Always ok to read 0 elements.
  540. if (I.ReadSize() == 0)
  541. {
  542. I.Information() = 0;
  543. return I.PnpComplete(this, STATUS_SUCCESS);
  544. }
  545. PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();
  546.     ULONG dwTotalSize = I.ReadSize(CURRENT);
  547. ULONG dwMaxSize = m_Endpoint2IN.MaximumTransferSize();
  548. // If the total requested read size is greater than the Maximum Transfer
  549. // Size for the Pipe, request to read only the Maximum Transfer Size since
  550. // the bus driver will fail an URB with a TransferBufferLength of greater
  551. // than the Maximum Transfer Size. 
  552. if (dwTotalSize > dwMaxSize)
  553. {
  554. ASSERT(dwMaxSize);
  555. dwTotalSize = dwMaxSize;
  556. }
  557. // Allocate a new context structure for Irp completion
  558. USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
  559. if (pCompInfo == NULL)
  560. {
  561. I.Information() = 0;
  562. return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
  563. }
  564. // TODO: Select the correct pipe to read from
  565. // Create an URB to do actual Bulk read from the pipe
  566. PURB pUrb = m_Endpoint2IN.BuildBulkTransfer(
  567.      pBuffer,       // Where is data coming from?
  568. dwTotalSize,   // How much data to read?
  569. TRUE,          // direction (TRUE = IN)
  570. NULL, // Link to next URB
  571. TRUE // Allow a short transfer
  572. );        
  573. if (pUrb == NULL)
  574. {
  575. delete pCompInfo;
  576. I.Information() = 0;
  577. return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
  578. }
  579. // Initialize context structure
  580. pCompInfo->m_pClass = this;
  581. pCompInfo->m_pUrb = pUrb;
  582.     // Submit the URB to our USB device
  583. NTSTATUS status;
  584. status = m_Endpoint2IN.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
  585. return status;
  586. }
  587. ////////////////////////////////////////////////////////////////////////
  588. //  ForUsbDevice::ReadComplete
  589. //
  590. // Routine Description:
  591. // Completion Handler for IRP_MJ_READ
  592. //
  593. // Parameters:
  594. // I - IRP just completed by USB
  595. // pContext - Context structure containing pointer to Urb
  596. //
  597. // Parameters:
  598. // NTSTATUS - STATUS_SUCCESS
  599. //
  600. // Comments:
  601. // This routine is called when USBD completes the read request
  602. //
  603. NTSTATUS ForUsbDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
  604. {
  605. // Normal completion routine code to propagate pending flag
  606. if (I->PendingReturned) 
  607. {
  608. I.MarkPending();
  609. }
  610. NTSTATUS status = I.Status();
  611. PURB pUrb = pContext->m_pUrb;
  612. ULONG nBytesRead = 0;
  613. if ( NT_SUCCESS(status) ) 
  614. {
  615. nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  616. if (nBytesRead > 0) 
  617. t << "Read() got " << nBytesRead<< " bytes from USBn";
  618.     }
  619. // Deallocate Urb and context structure
  620. delete pUrb;
  621. delete pContext;
  622. // set returned count
  623. I.Information() = nBytesRead;
  624. // Plug and Play accounting
  625. DecrementOutstandingRequestCount();
  626. // allow IRP completion processing
  627. return STATUS_SUCCESS;
  628. }
  629. ////////////////////////////////////////////////////////////////////////
  630. //  ForUsbDevice::Write
  631. //
  632. // Routine Description:
  633. // Handler for IRP_MJ_WRITE
  634. //
  635. // Parameters:
  636. // I - Current IRP
  637. //
  638. // Return Value:
  639. // NTSTATUS - Result code
  640. //
  641. // Comments:
  642. // This routine handles write requests.
  643. //
  644. // The KPnpDevice class handles restricting IRP flow
  645. // if the device is stopping or being removed.
  646. //
  647. NTSTATUS ForUsbDevice::Write(KIrp I) 
  648. {
  649. t << "Entering ForUsbDevice::Write, " << I << EOL;
  650. // TODO: Check the incoming request.  Replace "FALSE" in the following
  651. // line with a check that returns TRUE if the request is not valid.
  652.     if (FALSE)
  653. {
  654. // Invalid parameter in the Write request
  655. I.Information() = 0;
  656. return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
  657. }
  658. // Always ok to write 0 elements.
  659. if (I.WriteSize() == 0)
  660. {
  661. I.Information() = 0;
  662. return I.PnpComplete(this, STATUS_SUCCESS);
  663. }
  664. ULONG dwTotalSize = I.WriteSize(CURRENT);
  665. ULONG dwMaxSize = m_Endpoint2OUT.MaximumTransferSize();
  666. // If the total requested read size is greater than the Maximum Transfer
  667. // Size for the Pipe, request to read only the Maximum Transfer Size since
  668. // the bus driver will fail an URB with a TransferBufferLength of greater
  669. // than the Maximum Transfer Size. 
  670. if (dwTotalSize > dwMaxSize)
  671. {
  672. ASSERT(dwMaxSize);
  673. dwTotalSize = dwMaxSize;
  674. }
  675. PUCHAR pBuffer = (PUCHAR)I.BufferedWriteSource();
  676. KMemory Mem(pBuffer, dwTotalSize);
  677. Mem.SetPageArray();
  678. // Allocate a new context structure for Irp completion
  679. USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
  680. if (pCompInfo == NULL)
  681. {
  682. I.Information() = 0;
  683. return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
  684. }
  685. // TODO: Select the correct pipe to write to
  686. // Create an URB to do actual Bulk write to the pipe
  687. PURB pUrb = m_Endpoint2OUT.BuildBulkTransfer(
  688. Mem,          // Where is data coming from?
  689. dwTotalSize,  // How much data to read?
  690. FALSE,        // direction (FALSE = OUT)
  691. NULL   // Link to next URB
  692. );         
  693. if (pUrb == NULL)
  694. {
  695. delete pCompInfo;
  696. I.Information() = 0;
  697. return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
  698. }
  699. // Initialize context structure
  700. pCompInfo->m_pClass = this;
  701. pCompInfo->m_pUrb = pUrb;
  702.     // Submit the URB to our USB device
  703. NTSTATUS status;
  704. status = m_Endpoint2OUT.SubmitUrb(I, pUrb, LinkTo(WriteComplete), pCompInfo, 0);
  705. return status;
  706. }
  707. ////////////////////////////////////////////////////////////////////////
  708. //  ForUsbDevice::WriteComplete
  709. //
  710. // Routine Description:
  711. // Completion Handler for IRP_MJ_WRITE
  712. //
  713. // Parameters:
  714. // I - IRP just completed by USB
  715. // pContext - Context structure containing pointer to Urb
  716. //
  717. // Return Value:
  718. // NTSTATUS STATUS_SUCCESS
  719. //
  720. // Comments:
  721. // This routine is called when USBD completes the write request
  722. //
  723. NTSTATUS ForUsbDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
  724. {
  725. // Normal completion routine code to propagate pending flag
  726. if (I->PendingReturned) 
  727. {
  728. I.MarkPending();
  729. }
  730. NTSTATUS status = I.Status();
  731. PURB pUrb = pContext->m_pUrb;
  732. ULONG nBytesWritten = 0;
  733. if ( NT_SUCCESS(status) ) 
  734. {
  735. nBytesWritten = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  736. if (nBytesWritten > 0) 
  737. t << "Wrote " << nBytesWritten << " bytes to USBn";
  738.     }
  739. // Deallocate Urb and context structure
  740. delete pUrb;
  741. delete pContext;
  742. // set returned count
  743. I.Information() = nBytesWritten;
  744. // Plug and Play accounting
  745. DecrementOutstandingRequestCount();
  746. // allow IRP completion processing
  747. return STATUS_SUCCESS;
  748. }
  749. ////////////////////////////////////////////////////////////////////////
  750. //  ForUsbDevice::DeviceControl
  751. //
  752. // Routine Description:
  753. // Handler for IRP_MJ_DEVICE_CONTROL
  754. //
  755. // Parameters:
  756. // I - Current IRP
  757. // 
  758. // Return Value:
  759. // None
  760. //
  761. // Comments:
  762. // This routine is the first handler for Device Control requests.
  763. // The KPnpDevice class handles restricting IRP flow
  764. // if the device is stopping or being removed.
  765. //
  766. NTSTATUS ForUsbDevice::DeviceControl(KIrp I) 
  767. {
  768. NTSTATUS status;
  769. t << "Entering ForUsbDevice::Device Control, " << I << EOL;
  770. switch (I.IoctlCode())
  771. {
  772. case FORUSB_IOCTL_Test:
  773. status = FORUSB_IOCTL_Test_Handler(I);
  774. break;
  775. case FORUSB_IOCTL_Read:
  776. status = FORUSB_IOCTL_Read_Handler(I);
  777. break;
  778. case FORUSB_IOCTL_Write:
  779. status = FORUSB_IOCTL_Write_Handler(I);
  780. break;
  781. default:
  782. // Unrecognized IOCTL request
  783. status = STATUS_INVALID_PARAMETER;
  784. break;
  785. }
  786. // If the IRP's IOCTL handler deferred processing using some driver
  787. // specific scheme, the status variable is set to STATUS_PENDING.
  788. // In this case we simply return that status, and the IRP will be
  789. // completed later.  Otherwise, complete the IRP using the status
  790. // returned by the IOCTL handler.
  791. if (status == STATUS_PENDING)
  792. {
  793. return status;
  794. }
  795. else
  796. {
  797. return I.PnpComplete(this, status);
  798. }
  799. }
  800. ////////////////////////////////////////////////////////////////////////
  801. //  ForUsbDevice::FORUSB_IOCTL_Test_Handler
  802. //
  803. // Routine Description:
  804. // Handler for IO Control Code FORUSB_IOCTL_Test
  805. //
  806. // Parameters:
  807. // I - IRP containing IOCTL request
  808. //
  809. // Return Value:
  810. // NTSTATUS - Status code indicating success or failure
  811. //
  812. // Comments:
  813. // This routine implements the FORUSB_IOCTL_Test function.
  814. // This routine runs at passive level.
  815. //
  816. NTSTATUS ForUsbDevice::FORUSB_IOCTL_Test_Handler(KIrp I)
  817. {
  818. NTSTATUS status = STATUS_SUCCESS;
  819. t << "Entering ForUsbDevice::FORUSB_IOCTL_Test_Handler, " << I << EOL;
  820. // TODO: Verify that the input parameters are correct
  821. // If not, return STATUS_INVALID_PARAMETER
  822. // TODO: Handle the the FORUSB_IOCTL_Test request, or 
  823. // defer the processing of the IRP (i.e. by queuing) and set
  824. // status to STATUS_PENDING.
  825. // TODO: Assuming that the request was handled here. Set I.Information
  826. // to indicate how much data to copy back to the user.
  827. I.Information() = 0;
  828. return status;
  829. }
  830. ////////////////////////////////////////////////////////////////////////
  831. //  ForUsbDevice::FORUSB_IOCTL_Read_Handler
  832. //
  833. // Routine Description:
  834. // Handler for IO Control Code FORUSB_IOCTL_Read
  835. //
  836. // Parameters:
  837. // I - IRP containing IOCTL request
  838. //
  839. // Return Value:
  840. // NTSTATUS - Status code indicating success or failure
  841. //
  842. // Comments:
  843. // This routine implements the FORUSB_IOCTL_Read function.
  844. // This routine runs at passive level.
  845. //
  846. NTSTATUS ForUsbDevice::FORUSB_IOCTL_Read_Handler(KIrp I)
  847. {
  848. NTSTATUS status = STATUS_SUCCESS;
  849. t << "Entering ForUsbDevice::FORUSB_IOCTL_Read_Handler, " << I << EOL;
  850. // TODO: Verify that the input parameters are correct
  851. // If not, return STATUS_INVALID_PARAMETER
  852. // TODO: Handle the the FORUSB_IOCTL_Read request, or 
  853. // defer the processing of the IRP (i.e. by queuing) and set
  854. // status to STATUS_PENDING.
  855. // TODO: Assuming that the request was handled here. Set I.Information
  856. // to indicate how much data to copy back to the user.
  857. I.Information() = 0;
  858. unsigned char  key[16];
  859. key[0]=0xff;
  860. PURB  pUrb=m_Endpoint1IN.BuildInterruptTransfer(
  861.    (PVOID) key,
  862.    1,
  863.    TRUE,
  864.    NULL,
  865.    NULL,
  866.    TRUE
  867. );
  868. status=m_Endpoint1IN.SubmitUrb(
  869.    pUrb,
  870.    NULL,
  871.    NULL,
  872.    0
  873. );
  874. t<<key[0]<<"n";
  875. PUCHAR pdata=(PUCHAR)I.IoctlBuffer();
  876. *pdata=key[0];
  877. I.Information() = 1;
  878. return status;
  879. }
  880. ////////////////////////////////////////////////////////////////////////
  881. //  ForUsbDevice::FORUSB_IOCTL_Write_Handler
  882. //
  883. // Routine Description:
  884. // Handler for IO Control Code FORUSB_IOCTL_Write
  885. //
  886. // Parameters:
  887. // I - IRP containing IOCTL request
  888. //
  889. // Return Value:
  890. // NTSTATUS - Status code indicating success or failure
  891. //
  892. // Comments:
  893. // This routine implements the FORUSB_IOCTL_Write function.
  894. // This routine runs at passive level.
  895. //
  896. NTSTATUS ForUsbDevice::FORUSB_IOCTL_Write_Handler(KIrp I)
  897. {
  898. NTSTATUS status = STATUS_SUCCESS;
  899. t << "Entering ForUsbDevice::FORUSB_IOCTL_Write_Handler, " << I << EOL;
  900. // TODO: Verify that the input parameters are correct
  901. // If not, return STATUS_INVALID_PARAMETER
  902. // TODO: Handle the the FORUSB_IOCTL_Write request, or 
  903. // defer the processing of the IRP (i.e. by queuing) and set
  904. // status to STATUS_PENDING.
  905. // TODO: Assuming that the request was handled here. Set I.Information
  906. // to indicate how much data to copy back to the user.
  907. I.Information() = 0;
  908. // unsigned char S51data[16];
  909. // unsigned char * pdata=(unsigned char * )I.IoctlBuffer();
  910. // for(int i =0;i!=16;i++)S51data[i]=*pdata++;
  911. CHAR S51data[16];
  912. PCHAR m_Pdata=(PCHAR)I.IoctlBuffer();
  913. for(CHAR i=0;i!=16;i++)
  914. {
  915. S51data[i]=*m_Pdata++;
  916. t<<S51data[i]<<"n";
  917. }
  918. PURB  pUrb=m_Endpoint1OUT.BuildInterruptTransfer(
  919.    (PVOID) S51data,
  920.    16,
  921.    TRUE,
  922.    NULL,
  923.    NULL,
  924.    FALSE
  925. );
  926. status=m_Endpoint1OUT.SubmitUrb(
  927.    pUrb,
  928.    NULL,
  929.    NULL,
  930.    0
  931. );
  932. I.Information() =16;
  933. return status;
  934. }