Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1386 lines
45 KiB

  1. /*******************************************************************************
  2. * Copyright (c) 1997-1998 Gemplus Development
  3. *
  4. * Name : GNTSCR09.C (Gemplus NT Smart Card Reader module 09)
  5. *
  6. * Description : This is the main module which holds:
  7. * - the main functions for a standard NT driver
  8. *
  9. * Compiler : Microsoft DDK for Windows NT
  10. *
  11. * Host : IBM PC and compatible machines under Windows NT
  12. *
  13. * Release : 1.00.003
  14. *
  15. * Last Modif : 24/01/98: V1.00.003 (Gilles PAUZIE)
  16. * - Modifiy GDDKNT_09CreateDevice function. The IoCreateDevice
  17. * function is now always called with FALSE parameters for the
  18. * both compilator mode free and checked. This resolves the
  19. * problem of the IO pending for the free mode.
  20. * 22/12/97: V1.00.002 (Thierry Fabre)
  21. * - Modifiy GDDKNT_Cleanup function to abort a pending io-
  22. * request (wait for insertion/removal card).
  23. * 22/06/97: V1.00.001 (Gilles Pauzie)
  24. * - Start of development.
  25. *
  26. ********************************************************************************
  27. *
  28. * Warning :
  29. *
  30. * Remark :
  31. *
  32. *******************************************************************************/
  33. /*------------------------------------------------------------------------------
  34. Include section:
  35. - stdio.h: standards definitons.
  36. - ntddk.h: DDK Windows NT general definitons.
  37. - ntddser.h: DDK Windows NT serial management definitons.
  38. ------------------------------------------------------------------------------*/
  39. #include <stdio.h>
  40. #include <ntddk.h>
  41. #include <ntddser.h>
  42. /*------------------------------------------------------------------------------
  43. - smclib.h: smart card library definitions.
  44. ------------------------------------------------------------------------------*/
  45. #define SMARTCARD_POOL_TAG 'cGCS'
  46. #include <smclib.h>
  47. /*------------------------------------------------------------------------------
  48. - gemlog.h: Gemplus error log file definitions.
  49. - gioctl09.h: public interface definition for the IOCTL functions.
  50. - gntscr09.h: public interface definition for this module.
  51. - gntser.h: public interface definition for serial management
  52. ------------------------------------------------------------------------------*/
  53. #include "gemlog.h"
  54. #include "gemcore.h"
  55. #include "gioctl09.h"
  56. #include "gntscr09.h"
  57. #include "gntser.h"
  58. /*------------------------------------------------------------------------------
  59. Compiler Directives:
  60. ------------------------------------------------------------------------------*/
  61. #ifdef ALLOC_PRAGMA
  62. #pragma alloc_text(INIT, DriverEntry)
  63. #pragma alloc_text(INIT, GDDKNT_09AddDevice)
  64. #pragma alloc_text(INIT, GDDKNT_09CreateDevice)
  65. #endif // ALLOC_PRAGMA
  66. /*------------------------------------------------------------------------------
  67. Constant section:
  68. - SC_DRIVER_VERSION defines the version of the driver
  69. - IFD_STANDARD_BAUD_RATE defines the standard baud rate for the reader (9600)
  70. - MAX_DEVICES is the maximum number of devices (and instances) we want
  71. to support
  72. - POLLING_TIMEOUT is the polling timeout for detection insertion/removal card
  73. in milliseconds (1000 ms)
  74. ------------------------------------------------------------------------------*/
  75. #define SC_DRIVER_VERSION 0x090
  76. #define IFD_STANDARD_BAUD_RATE 9600
  77. #define MAX_DEVICES 16
  78. #define POLLING_TIMEOUT 1000
  79. /*------------------------------------------------------------------------------
  80. Function definition section:
  81. ------------------------------------------------------------------------------*/
  82. /*******************************************************************************
  83. * NTSTATUS DriverEntry
  84. * (
  85. * IN PDRIVER_OBJECT DriverObject,
  86. * IN PUNICODE_STRING RegistryPath
  87. * )
  88. * Description :
  89. * -------------
  90. * This routine is called at system initialization time to initialize
  91. * this driver.
  92. *
  93. * Remarks :
  94. * -------------
  95. * Nothing.
  96. *
  97. * In :
  98. * -------------
  99. * - DriverObject supplies the driver object.
  100. * - RegistryPath supplies the registry path for this driver.
  101. *
  102. * Out :
  103. * -------------
  104. * Nothing.
  105. *
  106. * Responses :
  107. * -------------
  108. * STATUS_SUCCESS - We could initialize at least one device.
  109. * STATUS_NO_SUCH_DEVICE - We could not initialize even one device.
  110. *******************************************************************************/
  111. NTSTATUS DriverEntry
  112. (
  113. IN PDRIVER_OBJECT DriverObject,
  114. IN PUNICODE_STRING RegistryPath
  115. )
  116. {
  117. ULONG
  118. serialNumber,
  119. ifdNumber,
  120. noOfDevices = 0,
  121. maxBaudRate,
  122. maximalIFD,
  123. IFDOption,
  124. i;
  125. NTSTATUS
  126. status;
  127. PSMARTCARD_EXTENSION
  128. previousDeviceExt = NULL;
  129. RTL_QUERY_REGISTRY_TABLE
  130. paramTable[4];
  131. UNICODE_STRING
  132. driverPath;
  133. WCHAR
  134. buffer[MAXIMUM_FILENAME_LENGTH];
  135. INT16
  136. response;
  137. USHORT
  138. rlen;
  139. BYTE
  140. rbuff[HOR3GLL_BUFFER_SIZE],
  141. sbuff[HOR3GLL_BUFFER_SIZE];
  142. #if DBG
  143. /*------------------------------------------------------------------------------
  144. Initialize the debug level.
  145. ------------------------------------------------------------------------------*/
  146. SmartcardSetDebugLevel(DEBUG_ALL);
  147. #endif
  148. /*------------------------------------------------------------------------------
  149. Initialize the Driver Object with driver's entry points
  150. ------------------------------------------------------------------------------*/
  151. DriverObject->DriverUnload = GDDKNT_09Unload;
  152. DriverObject->MajorFunction[IRP_MJ_CREATE] = GDDKNT_09CreateClose;
  153. DriverObject->MajorFunction[IRP_MJ_CLOSE] = GDDKNT_09CreateClose;
  154. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = GDDKNT_09Cleanup;
  155. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GDDKNT_09DeviceControl;
  156. /*------------------------------------------------------------------------------
  157. Read in the the driver registry path:
  158. - "MaximalBaudRate" is the maximal speed specified for the reader.
  159. - "MaximalIFD" is the maximal number of security modules for the reader.
  160. - "IFDOption" is the options for the reader.
  161. ------------------------------------------------------------------------------*/
  162. maxBaudRate = 0;
  163. RtlZeroMemory(paramTable,sizeof(paramTable));
  164. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  165. paramTable[0].Name = L"MaximalBaudRate";
  166. paramTable[0].EntryContext = &maxBaudRate;
  167. paramTable[0].DefaultType = REG_DWORD;
  168. paramTable[0].DefaultData = &maxBaudRate;
  169. paramTable[0].DefaultLength = sizeof(ULONG);
  170. maximalIFD = 0;
  171. paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  172. paramTable[1].Name = L"MaximalIFD";
  173. paramTable[1].EntryContext = &maximalIFD;
  174. paramTable[1].DefaultType = REG_DWORD;
  175. paramTable[1].DefaultData = &maximalIFD;
  176. paramTable[1].DefaultLength = sizeof(ULONG);
  177. IFDOption = 0;
  178. paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  179. paramTable[2].Name = L"IFDOption";
  180. paramTable[2].EntryContext = &IFDOption;
  181. paramTable[2].DefaultType = REG_DWORD;
  182. paramTable[2].DefaultData = &IFDOption;
  183. paramTable[2].DefaultLength = sizeof(ULONG);
  184. driverPath.Buffer = buffer;
  185. driverPath.MaximumLength = sizeof(buffer);
  186. driverPath.Length = 0;
  187. RtlCopyUnicodeString(&driverPath,RegistryPath);
  188. status =
  189. RtlQueryRegistryValues(
  190. RTL_REGISTRY_ABSOLUTE,
  191. driverPath.Buffer,
  192. &paramTable[0],
  193. NULL,
  194. NULL
  195. );
  196. if ((maxBaudRate != 9600lu) && (maxBaudRate != 19200lu) &&
  197. (maxBaudRate != 38400lu) && (maxBaudRate != 76800lu)
  198. )
  199. {
  200. maxBaudRate = IFD_STANDARD_BAUD_RATE;
  201. }
  202. /*------------------------------------------------------------------------------
  203. For all the serial ports we search if a Gemplus Oros Based reader is
  204. connected. If we found a reader, we create 1 device by IFD in the reader.
  205. For example we can have 2 devices for a GCR500 (1 for the main reader,
  206. 1 for the Security Access Module).
  207. ------------------------------------------------------------------------------*/
  208. for (serialNumber = 0;
  209. (serialNumber < HGTSER_MAX_PORT) && (noOfDevices < MAX_DEVICES);
  210. serialNumber++)
  211. {
  212. /*------------------------------------------------------------------------------
  213. Build a string like \Device\SerialN (N is the 0 based device number)
  214. ------------------------------------------------------------------------------*/
  215. UNICODE_STRING
  216. serialDeviceName, deviceNo, device;
  217. WCHAR
  218. buffer[32];
  219. serialDeviceName.Buffer = buffer;
  220. serialDeviceName.MaximumLength = sizeof(buffer);
  221. serialDeviceName.Length = 0;
  222. RtlInitUnicodeString(&device,L"\\Device\\Serial");
  223. RtlCopyUnicodeString(&serialDeviceName,&device);
  224. deviceNo.Buffer =
  225. serialDeviceName.Buffer +
  226. serialDeviceName.Length / sizeof(WCHAR);
  227. deviceNo.MaximumLength = 2 * sizeof(WCHAR);
  228. deviceNo.Length = 0;
  229. RtlIntegerToUnicodeString(serialNumber,10,&deviceNo);
  230. serialDeviceName.Length += deviceNo.Length;
  231. /*------------------------------------------------------------------------------
  232. Try to create a device for all the IFD availables in the reader
  233. ------------------------------------------------------------------------------*/
  234. for (ifdNumber=0;
  235. (ifdNumber<maximalIFD) && (ifdNumber<MAX_IFD_BY_READER);
  236. ifdNumber++)
  237. {
  238. status = GDDKNT_09AddDevice(
  239. DriverObject,
  240. &serialDeviceName,
  241. noOfDevices,
  242. serialNumber,
  243. ifdNumber,
  244. previousDeviceExt,
  245. maxBaudRate
  246. );
  247. if (status == STATUS_SUCCESS)
  248. {
  249. // We have successfully created a device
  250. PDEVICE_OBJECT deviceObject =
  251. DriverObject->DeviceObject;
  252. PDEVICE_EXTENSION deviceExtension =
  253. deviceObject->DeviceExtension;
  254. PSMARTCARD_EXTENSION smartcardExtension =
  255. &deviceExtension->SmartcardExtension;
  256. ASSERT(deviceObject != NULL);
  257. ASSERT(deviceExtension != NULL);
  258. ASSERT(smartcardExtension != NULL);
  259. smartcardExtension->ReaderExtension->MaximalIFD = maximalIFD;
  260. smartcardExtension->ReaderExtension->IFDOption = IFDOption;
  261. noOfDevices++;
  262. /*------------------------------------------------------------------------------
  263. If is the first IFD for the reader
  264. Save the DeviceObject for the next IFD.
  265. Read the type of the reader
  266. If the reader type is GCR410
  267. No more IFD available on this port
  268. ------------------------------------------------------------------------------*/
  269. if (ifdNumber == 0)
  270. {
  271. previousDeviceExt = smartcardExtension;
  272. /*------------------------------------------------------------------------------
  273. Read the type of the reader
  274. ------------------------------------------------------------------------------*/
  275. sbuff[0] = HOR3GLL_IFD_CMD_INFO;
  276. sbuff[1] = 0x01;
  277. rlen = HOR3GLL_BUFFER_SIZE;
  278. response = G_Oros3Exchange
  279. (
  280. (INT16)(noOfDevices-1),
  281. HOR3GLL_DEFAULT_TIME,
  282. (const WORD16)2,
  283. (const BYTE *)sbuff,
  284. &rlen,
  285. rbuff
  286. );
  287. /*------------------------------------------------------------------------------
  288. If the reader type is GCR410
  289. Then
  290. No more IFD available on this port
  291. ------------------------------------------------------------------------------*/
  292. if ((response != G_OK) || (rlen != 2) || (rbuff[0] != 0) || (rbuff[1] == 0x01))
  293. {
  294. break;
  295. }
  296. }
  297. }
  298. else
  299. {
  300. break;
  301. }
  302. }
  303. }
  304. /*------------------------------------------------------------------------------
  305. If we haven't found any reader on the serial, then we write a message in the
  306. event log file.
  307. ------------------------------------------------------------------------------*/
  308. if (noOfDevices == 0)
  309. {
  310. SmartcardLogError(
  311. DriverObject,
  312. GEM_NO_SUCH_DEVICE,
  313. NULL,
  314. status
  315. );
  316. return STATUS_NO_SUCH_DEVICE;
  317. }
  318. return STATUS_SUCCESS;
  319. }
  320. /*******************************************************************************
  321. * NTSTATUS GDDKNT_09AddDevice
  322. * (
  323. * IN PDRIVER_OBJECT DriverObject,
  324. * IN PUNICODE_STRING SerialDeviceName,
  325. * IN ULONG DeviceNumber,
  326. * IN ULONG SerialNumber,
  327. * IN ULONG IFDNumber,
  328. * IN PSMARTCARD_EXTENSION PreviousDeviceExt,
  329. * IN ULONG MaximalBaudRate
  330. * )
  331. *
  332. * Description :
  333. * -------------
  334. * This is the add-device routine.
  335. *
  336. * Remarks :
  337. * -------------
  338. * Nothing.
  339. *
  340. * In :
  341. * -------------
  342. * - DriverObject is a pointer to the driver object for this device.
  343. * - SerialDeviceName holds the device name of the serial port to attach to.
  344. * - DeviceNumber holds an ascending device number starting with 0.
  345. * - SerialNumber holds the serial port number (0 to 3).
  346. * - IFDNumber holds the numero of the IFD in
  347. * the reader (0 to MAX_IFD_BY_READER).
  348. * - PreviousDeviceExt holds the previous smart card object. It is used to
  349. * know the serial device object.
  350. * - MaximalBaudRate holds the maximal speed specified for the reader.
  351. * Out :
  352. * -------------
  353. * Nothing.
  354. *
  355. * Responses :
  356. * -------------
  357. * STATUS_SUCCESS Device created.
  358. *******************************************************************************/
  359. NTSTATUS GDDKNT_09AddDevice
  360. (
  361. IN PDRIVER_OBJECT DriverObject,
  362. IN PUNICODE_STRING SerialDeviceName,
  363. IN ULONG DeviceNumber,
  364. IN ULONG SerialNumber,
  365. IN ULONG IFDNumber,
  366. IN PSMARTCARD_EXTENSION PreviousDeviceExt,
  367. IN ULONG MaximalBaudRate
  368. )
  369. {
  370. UNICODE_STRING
  371. smartcardDeviceName, deviceNo, device;
  372. WCHAR
  373. buffer[64];
  374. NTSTATUS
  375. status;
  376. ASSERT(DriverObject != NULL);
  377. ASSERT(SerialDeviceName != NULL);
  378. ASSERT(DeviceNumber >= 0);
  379. ASSERT(SerialNumber >= 0);
  380. ASSERT(IFDNumber >= 0);
  381. /*------------------------------------------------------------------------------
  382. Build a device name for the smart card reader
  383. \Device\GemSCR09pi: p (0 to 3) is the port number,
  384. i (0 to MAX_IFD_BY_READER) is the 0 based IFD number
  385. ------------------------------------------------------------------------------*/
  386. smartcardDeviceName.Buffer = buffer;
  387. smartcardDeviceName.MaximumLength = sizeof(buffer);
  388. smartcardDeviceName.Length = 0;
  389. RtlInitUnicodeString(&device,L"\\Device\\GemSCR09");
  390. RtlCopyUnicodeString(&smartcardDeviceName,&device);
  391. /*------------------------------------------------------------------------------
  392. Add the port serial number
  393. ------------------------------------------------------------------------------*/
  394. deviceNo.Buffer =
  395. smartcardDeviceName.Buffer + smartcardDeviceName.Length / sizeof(WCHAR);
  396. deviceNo.MaximumLength = 2 * sizeof(WCHAR);
  397. deviceNo.Length = 0;
  398. RtlIntegerToUnicodeString(SerialNumber,16,&deviceNo);
  399. smartcardDeviceName.Length += deviceNo.Length;
  400. /*------------------------------------------------------------------------------
  401. Add the ifd number
  402. ------------------------------------------------------------------------------*/
  403. deviceNo.Buffer =
  404. smartcardDeviceName.Buffer + smartcardDeviceName.Length / sizeof(WCHAR);
  405. deviceNo.MaximumLength = 2 * sizeof(WCHAR);
  406. deviceNo.Length = 0;
  407. RtlIntegerToUnicodeString(IFDNumber,16,&deviceNo);
  408. smartcardDeviceName.Length += deviceNo.Length;
  409. /*------------------------------------------------------------------------------
  410. Try to create a device with the just created device name
  411. It is possible that a smart card device with this name
  412. already exists from a previous call.
  413. ------------------------------------------------------------------------------*/
  414. status = GDDKNT_09CreateDevice(
  415. DriverObject,
  416. &smartcardDeviceName,
  417. SerialDeviceName,
  418. DeviceNumber,
  419. SerialNumber,
  420. IFDNumber,
  421. PreviousDeviceExt,
  422. MaximalBaudRate
  423. );
  424. if (status == STATUS_SUCCESS)
  425. {
  426. PDEVICE_OBJECT
  427. deviceObject = DriverObject->DeviceObject;
  428. PDEVICE_EXTENSION
  429. deviceExtension = deviceObject->DeviceExtension;
  430. PSMARTCARD_EXTENSION
  431. smartcardExtension = &deviceExtension->SmartcardExtension;
  432. ASSERT(deviceObject != NULL);
  433. ASSERT(deviceExtension != NULL);
  434. ASSERT(smartcardExtension != NULL);
  435. }
  436. if (status != STATUS_OBJECT_NAME_COLLISION)
  437. {
  438. /*------------------------------------------------------------------------------
  439. The corresponding serial port is already in use
  440. So don't try to create a smart card device with a different name
  441. ------------------------------------------------------------------------------*/
  442. return status;
  443. }
  444. return status;
  445. }
  446. /*******************************************************************************
  447. * NTSTATUS GDDKNT_09CreateDevice
  448. * (
  449. * IN PDRIVER_OBJECT DriverObject,
  450. * IN PUNICODE_STRING SmartcardDeviceName,
  451. * IN PUNICODE_STRING SerialDeviceName,
  452. * IN ULONG DeviceNumber,
  453. * IN ULONG SerialNumber,
  454. * IN ULONG IFDNumber,
  455. * IN PSMARTCARD_EXTENSION PreviousDeviceExt,
  456. * IN ULONG MaximalBaudRate
  457. * )
  458. *
  459. * Description :
  460. * -------------
  461. * This routine creates an object for the physical device specified and
  462. * sets up the deviceExtension.
  463. *
  464. * Remarks :
  465. * -------------
  466. * Nothing.
  467. *
  468. * In :
  469. * -------------
  470. * - DriverObject is a pointer to the driver object for this device.
  471. * - SmartcardDeviceName holds the device name for this new device.
  472. * - SerialDeviceName holds the device name of the serial port to attach to.
  473. * - SerialNumber holds the serial port number (0 to 3).
  474. * - IFDNumber holds the numero of the IFD in the reader (0 to MAX_IFD_BY_READER).
  475. * - PreviousDeviceExt holds the previous smart card object. It is used to know the serial
  476. * device object.
  477. * - MaximalBaudRate holds the maximal speed specified for the reader.
  478. * Out :
  479. * -------------
  480. * Nothing.
  481. *
  482. * Responses :
  483. * -------------
  484. * STATUS_SUCCESS Device created.
  485. *******************************************************************************/
  486. NTSTATUS GDDKNT_09CreateDevice
  487. (
  488. IN PDRIVER_OBJECT DriverObject,
  489. IN PUNICODE_STRING SmartcardDeviceName,
  490. IN PUNICODE_STRING SerialDeviceName,
  491. IN ULONG DeviceNumber,
  492. IN ULONG SerialNumber,
  493. IN ULONG IFDNumber,
  494. IN PSMARTCARD_EXTENSION PreviousDeviceExt,
  495. IN ULONG MaximalBaudRate
  496. )
  497. {
  498. PFILE_OBJECT
  499. serialFileObject;
  500. PDEVICE_OBJECT
  501. deviceObject, serialDeviceObject;
  502. PDEVICE_EXTENSION
  503. deviceExtension;
  504. NTSTATUS
  505. status = STATUS_SUCCESS;
  506. ULONG
  507. i;
  508. ASSERT(DriverObject != NULL);
  509. ASSERT(SmartcardDeviceName != NULL);
  510. ASSERT(SerialDeviceName != NULL);
  511. ASSERT(DeviceNumber >= 0);
  512. ASSERT(SerialNumber >= 0);
  513. ASSERT(IFDNumber >= 0);
  514. SmartcardDebug(
  515. DEBUG_DRIVER,
  516. ("GEMSCR09!GDDKNT_09CreateDevice: DeviceNumber=%ld IFDNumber=%ld SerialDeviceName=%ws\n",
  517. DeviceNumber,
  518. IFDNumber,
  519. SerialDeviceName->Buffer)
  520. );
  521. /*------------------------------------------------------------------------------
  522. For the first IFD in the reader we try to get a pointer on the serial driver
  523. If we can't have a pointer on the serial object, perhaps the serial port
  524. is already used by an other device.
  525. ------------------------------------------------------------------------------*/
  526. if (IFDNumber == 0)
  527. {
  528. status = IoGetDeviceObjectPointer(
  529. SerialDeviceName,
  530. FILE_ALL_ACCESS,
  531. &serialFileObject,
  532. &serialDeviceObject
  533. );
  534. SmartcardDebug(
  535. DEBUG_DRIVER,
  536. ("GEMSCR09!GDDKNT_09CreateDevice: IoGetDeviceObjectPointer=%lX\n",status)
  537. );
  538. if (!NT_SUCCESS(status))
  539. {
  540. return status;
  541. }
  542. ASSERT(serialFileObject != NULL);
  543. ASSERT(serialDeviceObject != NULL);
  544. }
  545. /*------------------------------------------------------------------------------
  546. Try to create a new device smart card object
  547. ------------------------------------------------------------------------------*/
  548. status = IoCreateDevice(
  549. DriverObject,
  550. sizeof(DEVICE_EXTENSION),
  551. SmartcardDeviceName,
  552. FILE_DEVICE_SMARTCARD,
  553. 0,
  554. FALSE,
  555. &deviceObject
  556. );
  557. SmartcardDebug(
  558. DEBUG_DRIVER,
  559. ("GEMSCR09!GDDKNT_09CreateDevice: IoCreateDevice=%lX\n",status)
  560. );
  561. /*------------------------------------------------------------------------------
  562. If we have failed to create a new device, then we write a message in the
  563. event log file.
  564. ------------------------------------------------------------------------------*/
  565. if (!NT_SUCCESS(status))
  566. {
  567. if (IFDNumber == 0)
  568. {
  569. ObDereferenceObject(serialFileObject);
  570. }
  571. SmartcardLogError(
  572. DriverObject,
  573. GEM_CANT_CREATE_DEVICE,
  574. SmartcardDeviceName,
  575. status
  576. );
  577. return status;
  578. }
  579. ASSERT(deviceObject != NULL);
  580. /*------------------------------------------------------------------------------
  581. Now we have a pointer on the new device and we try to allocate memory for
  582. the ReaderExtension struct.
  583. ------------------------------------------------------------------------------*/
  584. deviceExtension = deviceObject->DeviceExtension;
  585. ASSERT(deviceExtension != NULL);
  586. deviceObject->Flags = deviceObject->Flags | DO_BUFFERED_IO;
  587. RtlZeroMemory(deviceExtension,sizeof(PDEVICE_EXTENSION));
  588. deviceExtension->SmartcardExtension.ReaderExtension =
  589. ExAllocatePool(
  590. NonPagedPool,
  591. sizeof(READER_EXTENSION)
  592. );
  593. if (deviceExtension->SmartcardExtension.ReaderExtension == NULL)
  594. {
  595. SmartcardLogError(
  596. DriverObject,
  597. GEM_NO_MEMORY_FOR_READER_EXTENSION,
  598. SmartcardDeviceName,
  599. 0
  600. );
  601. status = STATUS_INSUFFICIENT_RESOURCES;
  602. }
  603. if (status == STATUS_SUCCESS)
  604. {
  605. SmartcardDebug(
  606. DEBUG_DRIVER,
  607. ("GEMSCR09!GDDKNT_09CreateDevice: SmartcardExtension=%lX\n",
  608. &(deviceExtension->SmartcardExtension))
  609. );
  610. /*------------------------------------------------------------------------------
  611. Write the version of the lib we use to the smartcard extension
  612. ------------------------------------------------------------------------------*/
  613. (deviceExtension->SmartcardExtension).Version = SMCLIB_VERSION;
  614. /*------------------------------------------------------------------------------
  615. Now let the lib allocate the buffer for data transmission
  616. We can either tell the lib how big the buffer should be by assigning a
  617. value to BufferSize or let the lib allocate the default size
  618. ------------------------------------------------------------------------------*/
  619. deviceExtension->SmartcardExtension.SmartcardRequest.BufferSize =
  620. MIN_BUFFER_SIZE;
  621. deviceExtension->SmartcardExtension.SmartcardReply.BufferSize =
  622. MIN_BUFFER_SIZE;
  623. status = SmartcardInitialize(&deviceExtension->SmartcardExtension);
  624. SmartcardDebug(
  625. DEBUG_DRIVER,
  626. ("GEMSCR09!GDDKNT_09CreateDevice: SmartcardInitialize=%lX\n",status)
  627. );
  628. if (status != STATUS_SUCCESS)
  629. {
  630. SmartcardLogError(
  631. DriverObject,
  632. GEM_CANT_INITIALIZE_SMCLIB,
  633. SmartcardDeviceName,
  634. status
  635. );
  636. }
  637. }
  638. /*------------------------------------------------------------------------------
  639. If SmartCardInitialize success
  640. We flush the ReaderExtension struct
  641. ------------------------------------------------------------------------------*/
  642. if (status == STATUS_SUCCESS)
  643. {
  644. RtlZeroMemory(
  645. deviceExtension->SmartcardExtension.ReaderExtension,
  646. sizeof(READER_EXTENSION)
  647. );
  648. /*------------------------------------------------------------------------------
  649. Save the deviceObject
  650. ------------------------------------------------------------------------------*/
  651. deviceExtension->SmartcardExtension.OsData->DeviceObject =
  652. deviceObject;
  653. /*------------------------------------------------------------------------------
  654. Save the deviceObject and the FileObject for the connected serial port
  655. ------------------------------------------------------------------------------*/
  656. if (IFDNumber == 0)
  657. {
  658. deviceExtension->SmartcardExtension.ReaderExtension->ConnectedSerialPort =
  659. serialDeviceObject;
  660. deviceExtension->SmartcardExtension.ReaderExtension->SerialFileObject =
  661. serialFileObject;
  662. }
  663. else
  664. {
  665. deviceExtension->SmartcardExtension.ReaderExtension->ConnectedSerialPort =
  666. PreviousDeviceExt->ReaderExtension->ConnectedSerialPort;
  667. deviceExtension->SmartcardExtension.ReaderExtension->SerialFileObject =
  668. PreviousDeviceExt->ReaderExtension->SerialFileObject;
  669. }
  670. /*------------------------------------------------------------------------------
  671. Save the serial port number this device is connected to
  672. ------------------------------------------------------------------------------*/
  673. deviceExtension->SmartcardExtension.ReaderCapabilities.Channel = SerialNumber;
  674. /*------------------------------------------------------------------------------
  675. Now we verify if a GemCore based reader is connected on this serial port.
  676. ------------------------------------------------------------------------------*/
  677. status = GDDK_09OpenChannel(
  678. &deviceExtension->SmartcardExtension,
  679. DeviceNumber,
  680. SerialNumber,
  681. IFDNumber,
  682. MaximalBaudRate
  683. );
  684. SmartcardDebug(
  685. DEBUG_DRIVER,
  686. ("GEMSCR09!GDDKNT_09CreateDevice: GDDK_09OpenChannel=%lX\n",status)
  687. );
  688. /*------------------------------------------------------------------------------
  689. If we have found a GemCore based reader connected on this serial port.
  690. Then
  691. Set up the call back functions
  692. (nota: RDF_CARD_EJECT and RDF_READER_SWALLOW are not supported)
  693. ------------------------------------------------------------------------------*/
  694. if (NT_SUCCESS(status))
  695. {
  696. deviceExtension->SmartcardExtension.ReaderFunction[RDF_TRANSMIT] =
  697. GDDK_09Transmit;
  698. deviceExtension->SmartcardExtension.ReaderFunction[RDF_SET_PROTOCOL] =
  699. GDDK_09SetProtocol;
  700. deviceExtension->SmartcardExtension.ReaderFunction[RDF_CARD_POWER] =
  701. GDDK_09ReaderPower;
  702. deviceExtension->SmartcardExtension.ReaderFunction[RDF_CARD_TRACKING] =
  703. GDDK_09CardTracking;
  704. /*------------------------------------------------------------------------------
  705. Create a symbolic link with the SMCLIB for this new device
  706. ------------------------------------------------------------------------------*/
  707. status = SmartcardCreateLink(
  708. &deviceExtension->SmartcardExtension.ReaderExtension->DosDeviceName,
  709. SmartcardDeviceName
  710. );
  711. if (status != STATUS_SUCCESS)
  712. {
  713. SmartcardLogError(
  714. DriverObject,
  715. GEM_CREATE_LINK_FAILED,
  716. SmartcardDeviceName,
  717. status
  718. );
  719. }
  720. }
  721. }
  722. /*------------------------------------------------------------------------------
  723. If we have failed anywhere above, we need to free the memory and the device
  724. ------------------------------------------------------------------------------*/
  725. if (status != STATUS_SUCCESS)
  726. {
  727. ExFreePool(deviceExtension->SmartcardExtension.ReaderExtension);
  728. SmartcardExit(&deviceExtension->SmartcardExtension);
  729. IoDeleteDevice(deviceObject);
  730. if (IFDNumber == 0)
  731. {
  732. ObDereferenceObject(serialFileObject);
  733. }
  734. }
  735. else
  736. {
  737. SmartcardDebug(
  738. DEBUG_DRIVER,
  739. ("GEMSCR09!GDDKNT_09CreateDevice: Device %ws created\n",
  740. deviceExtension->SmartcardExtension.ReaderExtension->DosDeviceName.Buffer)
  741. );
  742. }
  743. return status;
  744. }
  745. /*******************************************************************************
  746. * NTSTATUS GDDKNT_09CreateClose
  747. * (
  748. * IN PDEVICE_OBJECT DeviceObject,
  749. * IN PIRP Irp
  750. * )
  751. *
  752. * Description :
  753. * -------------
  754. * This routine is called by the I/O system when the device is opened or closed.
  755. *
  756. * Remarks :
  757. * -------------
  758. * Nothing.
  759. *
  760. * In :
  761. * -------------
  762. * - DeviceObject is a pointer to the device.
  763. * - Irp holds the Irp involved.
  764. * Out :
  765. * -------------
  766. * Nothing.
  767. *
  768. * Responses :
  769. * -------------
  770. * STATUS_SUCCESS
  771. *******************************************************************************/
  772. NTSTATUS GDDKNT_09CreateClose
  773. (
  774. IN PDEVICE_OBJECT DeviceObject,
  775. IN PIRP Irp
  776. )
  777. {
  778. NTSTATUS
  779. status;
  780. KEVENT
  781. event;
  782. LARGE_INTEGER
  783. timeout;
  784. PDEVICE_EXTENSION
  785. deviceExtension = DeviceObject->DeviceExtension;
  786. PSMARTCARD_EXTENSION
  787. smartcardExtension = &deviceExtension->SmartcardExtension;
  788. PIO_STACK_LOCATION
  789. irpStack = IoGetCurrentIrpStackLocation(Irp);
  790. ASSERT(deviceExtension != NULL);
  791. ASSERT(smartcardExtension != NULL);
  792. ASSERT(irpStack != NULL);
  793. if (irpStack->MajorFunction == IRP_MJ_CREATE)
  794. {
  795. SmartcardDebug(
  796. DEBUG_DRIVER,
  797. ("GEMSCR09!GDDKNT_09CreateClose: Device %ws opened\n",
  798. smartcardExtension->ReaderExtension->DosDeviceName.Buffer)
  799. );
  800. if (smartcardExtension->ReaderExtension->IFDNumber == 0)
  801. {
  802. /*------------------------------------------------------------------------------
  803. Update the current state of reader (card present/removed)
  804. Initialize the Card Tracking only if the reader can support this function.
  805. ------------------------------------------------------------------------------*/
  806. GDDK_09UpdateCardStatus(smartcardExtension);
  807. status = GDDKNT_09InitializeCardTracking(smartcardExtension);
  808. if (status != STATUS_SUCCESS)
  809. {
  810. SmartcardLogError(
  811. DeviceObject,
  812. GEM_CREATE_CARD_TRACKING_THREAD,
  813. &smartcardExtension->ReaderExtension->DosDeviceName,
  814. status
  815. );
  816. }
  817. }
  818. }
  819. else
  820. {
  821. SmartcardDebug(
  822. DEBUG_DRIVER,
  823. ("GEMSCR09!GDDKNT_09CreateClose: Device %ws closed\n",
  824. smartcardExtension->ReaderExtension->DosDeviceName.Buffer)
  825. );
  826. /*------------------------------------------------------------------------------
  827. Stop the card tracking thread
  828. ------------------------------------------------------------------------------*/
  829. if ((smartcardExtension->ReaderExtension->IFDNumber == 0) &&
  830. (smartcardExtension->ReaderExtension->CardStatus.Mode == RUN_IN_PROCESS))
  831. {
  832. smartcardExtension->ReaderExtension->CardStatus.Mode = STOP_REQUEST;
  833. KeInitializeEvent(&event,NotificationEvent,FALSE);
  834. while (smartcardExtension->ReaderExtension->CardStatus.Mode == STOP_REQUEST)
  835. {
  836. timeout.QuadPart = -((LONGLONG)100*10*1000);
  837. status = KeWaitForSingleObject(&event,
  838. Suspended,
  839. KernelMode,
  840. FALSE,
  841. &timeout);
  842. }
  843. }
  844. }
  845. Irp->IoStatus.Information = 0;
  846. Irp->IoStatus.Status = STATUS_SUCCESS;
  847. SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09CreateClose: Exit\n"));
  848. return STATUS_SUCCESS;
  849. }
  850. /*******************************************************************************
  851. * NTSTATUS GDDKNT_09Cleanup
  852. * (
  853. * IN PDEVICE_OBJECT DeviceObject,
  854. * IN PIRP Irp
  855. * )
  856. *
  857. * Description :
  858. * -------------
  859. * This routine is called by the I/O system when the device is opened or closed.
  860. *
  861. * Remarks :
  862. * -------------
  863. * Nothing.
  864. *
  865. * In :
  866. * -------------
  867. * - DeviceObject is a pointer to the device.
  868. * - Irp holds the Irp involved.
  869. * Out :
  870. * -------------
  871. * Nothing.
  872. *
  873. * Responses :
  874. * -------------
  875. * STATUS_SUCCESS
  876. *******************************************************************************/
  877. NTSTATUS GDDKNT_09Cleanup
  878. (
  879. IN PDEVICE_OBJECT DeviceObject,
  880. IN PIRP Irp
  881. )
  882. {
  883. PDEVICE_EXTENSION
  884. deviceExtension = DeviceObject->DeviceExtension;
  885. PSMARTCARD_EXTENSION
  886. smartcardExtension = &deviceExtension->SmartcardExtension;
  887. NTSTATUS
  888. status = STATUS_SUCCESS;
  889. ASSERT(deviceExtension != NULL);
  890. ASSERT(smartcardExtension != NULL);
  891. SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Cleanup: Enter\n"));
  892. if (Irp != NULL)
  893. {
  894. Irp->IoStatus.Information = 0;
  895. Irp->IoStatus.Status = STATUS_CANCELLED;
  896. if (Irp->Cancel == TRUE)
  897. {
  898. IoReleaseCancelSpinLock(Irp->CancelIrql);
  899. }
  900. else
  901. {
  902. Irp->IoStatus.Information = 0;
  903. Irp->IoStatus.Status = STATUS_SUCCESS;
  904. }
  905. smartcardExtension->OsData->NotificationIrp = NULL;
  906. SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Cleanup: Wait cancelled\n"));
  907. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  908. }
  909. SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Cleanup: Exit\n"));
  910. return STATUS_SUCCESS;
  911. }
  912. /*******************************************************************************
  913. * VOID GDDKNT_09Unload
  914. * (
  915. * IN PDRIVER_OBJECT DriverObject
  916. * )
  917. *
  918. * Description :
  919. * -------------
  920. * The driver unload routine. This is called by the I/O system when the
  921. * device is unloaded from memory.
  922. *
  923. * Remarks :
  924. * -------------
  925. * Nothing.
  926. *
  927. * In :
  928. * -------------
  929. * - DriverObject is a pointer to the driver object for this device.
  930. * Out :
  931. * -------------
  932. * Nothing.
  933. *
  934. * Responses :
  935. * -------------
  936. * Nothing.
  937. *******************************************************************************/
  938. VOID GDDKNT_09Unload
  939. (
  940. IN PDRIVER_OBJECT DriverObject
  941. )
  942. {
  943. PDEVICE_OBJECT
  944. deviceObject = DriverObject->DeviceObject;
  945. NTSTATUS
  946. status;
  947. WORD16
  948. LengthOut = 0;
  949. KEVENT
  950. event;
  951. LARGE_INTEGER
  952. timeout;
  953. ASSERT(deviceObject != NULL);
  954. SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Unload: Enter\n"));
  955. do
  956. {
  957. PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
  958. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  959. SmartcardDebug(
  960. DEBUG_DRIVER,
  961. ("GEMSCR09!GDDKNT_09Unload: Unloading device %ws\n",
  962. smartcardExtension->ReaderExtension->DosDeviceName.Buffer)
  963. );
  964. /*------------------------------------------------------------------------------
  965. Close the communication with the reader
  966. ------------------------------------------------------------------------------*/
  967. GDDK_09CloseChannel(smartcardExtension);
  968. /*------------------------------------------------------------------------------
  969. We do not longet need the reference to the serial reader.
  970. ------------------------------------------------------------------------------*/
  971. ObDereferenceObject(smartcardExtension->ReaderExtension->SerialFileObject);
  972. /*------------------------------------------------------------------------------
  973. Delete the symbolic link of the smart card reader
  974. ------------------------------------------------------------------------------*/
  975. IoDeleteSymbolicLink(&smartcardExtension->ReaderExtension->DosDeviceName);
  976. /*------------------------------------------------------------------------------
  977. Let the lib free the send/receive buffers (SmartCardExit)
  978. ------------------------------------------------------------------------------*/
  979. SmartcardExit(smartcardExtension);
  980. /*------------------------------------------------------------------------------
  981. Free all allocated buffer
  982. ------------------------------------------------------------------------------*/
  983. ExFreePool(smartcardExtension->ReaderExtension->DosDeviceName.Buffer);
  984. ExFreePool(smartcardExtension->ReaderExtension);
  985. /*------------------------------------------------------------------------------
  986. Delete the device from the system
  987. ------------------------------------------------------------------------------*/
  988. IoDeleteDevice(deviceObject);
  989. } while(deviceObject == DriverObject->DeviceObject);
  990. SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Unload: Exit\n"));
  991. }
  992. /*******************************************************************************
  993. * NTSTATUS GDDKNT_09InitializeCardTracking
  994. * (
  995. * PSMARTCARD_EXTENSION SmartcardExtension
  996. * )
  997. *
  998. * Description :
  999. * -------------
  1000. * This routine initialized card tracking. It calls the serial driver to
  1001. * set a wait mask for RING tracking. After that it installs a completion
  1002. * routine to be called when RING changes state.
  1003. *
  1004. * Remarks :
  1005. * -------------
  1006. * Nothing.
  1007. *
  1008. * In :
  1009. * -------------
  1010. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1011. * the current device.
  1012. * Out :
  1013. * -------------
  1014. * Nothing.
  1015. *
  1016. * Responses :
  1017. * -------------
  1018. * NTSTATUS
  1019. *******************************************************************************/
  1020. NTSTATUS GDDKNT_09InitializeCardTracking
  1021. (
  1022. PSMARTCARD_EXTENSION SmartcardExtension
  1023. )
  1024. {
  1025. NTSTATUS
  1026. status;
  1027. LARGE_INTEGER
  1028. timeout;
  1029. /*------------------------------------------------------------------------------
  1030. Create which will check the status of the reader (card absent/present)
  1031. ------------------------------------------------------------------------------*/
  1032. SmartcardExtension->ReaderExtension->CardStatus.Mode = RUN_REQUEST;
  1033. status = PsCreateSystemThread(
  1034. &(SmartcardExtension->ReaderExtension->CardStatus.ThreadHandle),
  1035. THREAD_ALL_ACCESS,
  1036. NULL,
  1037. NULL,
  1038. NULL,
  1039. GDDKNT_09UpdateCardStatus,
  1040. SmartcardExtension);
  1041. SmartcardDebug(
  1042. DEBUG_TRACE,
  1043. ("GEMSCR09!GDDKNT_09InitializeCardTracking(%d)\n",status)
  1044. );
  1045. return status;
  1046. }
  1047. /*******************************************************************************
  1048. * VOID GDDKNT_09UpdateCardStatus
  1049. * (
  1050. * IN PKDPC EventDpc,
  1051. * IN PSMARTCARD_EXTENSION SmartcardExtension,
  1052. * IN PVOID SystemArgument1,
  1053. * IN PVOID SystemArgument2
  1054. * )
  1055. *
  1056. * Description :
  1057. * -------------
  1058. * This routine is called as the deferred procedure when RxD changes its status.
  1059. * Calls the serial driver again to start new RxD tracking.
  1060. *
  1061. * Remarks :
  1062. * -------------
  1063. * Nothing.
  1064. *
  1065. * In :
  1066. * -------------
  1067. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1068. * the current device.
  1069. * Out :
  1070. * -------------
  1071. * Nothing.
  1072. *
  1073. * Responses :
  1074. * -------------
  1075. * Nothing.
  1076. *******************************************************************************/
  1077. VOID GDDKNT_09UpdateCardStatus
  1078. (
  1079. IN PSMARTCARD_EXTENSION SmartcardExtension
  1080. )
  1081. {
  1082. NTSTATUS
  1083. status;
  1084. KIRQL
  1085. oldIrql;
  1086. KEVENT
  1087. event;
  1088. LARGE_INTEGER
  1089. timeout;
  1090. ULONG
  1091. CurrentState;
  1092. PIRP
  1093. pIrp;
  1094. /*------------------------------------------------------------------------------
  1095. Run the update card status while the function is not stopped.
  1096. ------------------------------------------------------------------------------*/
  1097. SmartcardExtension->ReaderExtension->CardStatus.Mode = RUN_IN_PROCESS;
  1098. while (SmartcardExtension->ReaderExtension->CardStatus.Mode == RUN_IN_PROCESS)
  1099. {
  1100. KeInitializeEvent(&event,NotificationEvent,FALSE);
  1101. timeout.QuadPart = -((LONGLONG) POLLING_TIMEOUT*10*1000);
  1102. status = KeWaitForSingleObject(&event,
  1103. Suspended,
  1104. KernelMode,
  1105. FALSE,
  1106. &timeout);
  1107. GDDK_09LockExchange(SmartcardExtension);
  1108. /*------------------------------------------------------------------------------
  1109. Save the current state of reader (card present/removed)
  1110. and read the new state
  1111. ------------------------------------------------------------------------------*/
  1112. CurrentState = SmartcardExtension->ReaderCapabilities.CurrentState;
  1113. GDDK_09UpdateCardStatus(SmartcardExtension);
  1114. /*------------------------------------------------------------------------------
  1115. Only inform the user of a card insertion/removal event
  1116. if this function isn't called due to a power down - power up cycle
  1117. ------------------------------------------------------------------------------*/
  1118. if (
  1119. (((CurrentState != SCARD_ABSENT) && (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_ABSENT))
  1120. ||
  1121. ((CurrentState == SCARD_ABSENT) && (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_ABSENT))
  1122. )
  1123. &&
  1124. (SmartcardExtension->OsData->NotificationIrp)
  1125. )
  1126. {
  1127. /*------------------------------------------------------------------------------
  1128. If the user had setup an irp for event tracking complete that irp now
  1129. ------------------------------------------------------------------------------*/
  1130. IoAcquireCancelSpinLock(&oldIrql);
  1131. IoSetCancelRoutine(SmartcardExtension->OsData->NotificationIrp,NULL);
  1132. IoReleaseCancelSpinLock(oldIrql);
  1133. SmartcardExtension->OsData->NotificationIrp->IoStatus.Information = 0;
  1134. SmartcardExtension->OsData->NotificationIrp->IoStatus.Status = STATUS_SUCCESS;
  1135. SmartcardDebug(
  1136. DEBUG_DRIVER,
  1137. ("GEMSCR09!GDDKNT_09UpdateCardStatus: Completing IRP %lx",
  1138. SmartcardExtension->OsData->NotificationIrp)
  1139. );
  1140. pIrp = SmartcardExtension->OsData->NotificationIrp;
  1141. SmartcardExtension->OsData->NotificationIrp = NULL;
  1142. IoCompleteRequest(
  1143. pIrp,
  1144. IO_NO_INCREMENT
  1145. );
  1146. }
  1147. GDDK_09UnlockExchange(SmartcardExtension);
  1148. }
  1149. /*------------------------------------------------------------------------------
  1150. Stop the update card status
  1151. ------------------------------------------------------------------------------*/
  1152. SmartcardDebug(
  1153. DEBUG_TRACE,
  1154. ("GEMSCR09!GDDKNT_09UpdateCardStatus: PsTerminateSystemThread\n")
  1155. );
  1156. SmartcardExtension->ReaderExtension->CardStatus.Mode = STOP_IN_PROCESS;
  1157. status = PsTerminateSystemThread(STATUS_SUCCESS);
  1158. }
  1159. /*******************************************************************************
  1160. * NTSTATUS GDDKNT_09DeviceControl
  1161. * (
  1162. * PDEVICE_OBJECT pDeviceObject,
  1163. * PIRP pIrp
  1164. * )
  1165. *
  1166. * Description :
  1167. * -------------
  1168. * This routine is called when a IOCTL_SMARTCARD_ is send to the driver.
  1169. *
  1170. * Remarks :
  1171. * -------------
  1172. * Nothing.
  1173. *
  1174. * In :
  1175. * -------------
  1176. * - pDeviceObject is a pointer to the device.
  1177. * - Irp holds the Irp involved.
  1178. *
  1179. * Out :
  1180. * -------------
  1181. * Nothing.
  1182. *
  1183. * Responses :
  1184. * -------------
  1185. * NTSTATUS
  1186. *******************************************************************************/
  1187. NTSTATUS GDDKNT_09DeviceControl
  1188. (
  1189. PDEVICE_OBJECT pDeviceObject,
  1190. PIRP pIrp
  1191. )
  1192. {
  1193. NTSTATUS
  1194. status = STATUS_SUCCESS;
  1195. ULONG
  1196. ioControlCode;
  1197. PDEVICE_EXTENSION
  1198. deviceExtension = pDeviceObject->DeviceExtension;
  1199. PSMARTCARD_EXTENSION
  1200. smartcardExtension = &deviceExtension->SmartcardExtension;
  1201. PIO_STACK_LOCATION
  1202. irpStack = IoGetCurrentIrpStackLocation(pIrp);
  1203. ASSERT(deviceExtension != NULL);
  1204. ASSERT(smartcardExtension != NULL);
  1205. ASSERT(irpStack != NULL);
  1206. /*------------------------------------------------------------------------------
  1207. Read the current IOCTL.
  1208. ------------------------------------------------------------------------------*/
  1209. ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
  1210. SmartcardDebug(DEBUG_TRACE,("GEMSCR09!GDDKNT_09DeviceControl: IoControlCode=%lX\n",
  1211. ioControlCode));
  1212. /*------------------------------------------------------------------------------
  1213. If the IOCTL > 0x7FFFFFFF
  1214. Then
  1215. Is a Gemplus reader specific IOCTL
  1216. ------------------------------------------------------------------------------*/
  1217. if (ioControlCode > 0x7FFFFFFF)
  1218. {
  1219. status =
  1220. GDDK_09SpecificIOCTL(
  1221. smartcardExtension,
  1222. ioControlCode,
  1223. irpStack->Parameters.DeviceIoControl.InputBufferLength,
  1224. pIrp->AssociatedIrp.SystemBuffer,
  1225. irpStack->Parameters.DeviceIoControl.OutputBufferLength,
  1226. pIrp->AssociatedIrp.SystemBuffer,
  1227. smartcardExtension->IoRequest.Information
  1228. );
  1229. IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  1230. pIrp->IoStatus.Status = status;
  1231. }
  1232. /*------------------------------------------------------------------------------
  1233. Else
  1234. Is a standard Smart card IOCTL
  1235. If is a GET_ATTRIBUTE/SET_ATTRIBUTE with a specific Tag
  1236. Then
  1237. Is a Specific vendor Tag
  1238. ------------------------------------------------------------------------------*/
  1239. else
  1240. {
  1241. if (
  1242. (
  1243. (ioControlCode == IOCTL_SMARTCARD_GET_ATTRIBUTE) ||
  1244. (ioControlCode == IOCTL_SMARTCARD_SET_ATTRIBUTE)
  1245. )
  1246. &&
  1247. ( (ULONG) irpStack->Parameters.DeviceIoControl.InputBufferLength >=
  1248. (ULONG) sizeof(ULONG)
  1249. )
  1250. &&
  1251. ( SCARD_CLASS(
  1252. (ULONG) *((PULONG)pIrp->AssociatedIrp.SystemBuffer)
  1253. ) == SCARD_CLASS_VENDOR_DEFINED
  1254. )
  1255. )
  1256. {
  1257. status =
  1258. GDDK_09SpecificTag(
  1259. smartcardExtension,
  1260. ioControlCode,
  1261. irpStack->Parameters.DeviceIoControl.InputBufferLength,
  1262. pIrp->AssociatedIrp.SystemBuffer,
  1263. irpStack->Parameters.DeviceIoControl.OutputBufferLength,
  1264. pIrp->AssociatedIrp.SystemBuffer,
  1265. smartcardExtension->IoRequest.Information
  1266. );
  1267. IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  1268. pIrp->IoStatus.Status = status;
  1269. }
  1270. /*------------------------------------------------------------------------------
  1271. Else
  1272. Call the SmartcardDeviceControl
  1273. ------------------------------------------------------------------------------*/
  1274. else
  1275. {
  1276. status = SmartcardDeviceControl(smartcardExtension,pIrp);
  1277. }
  1278. }
  1279. SmartcardDebug(DEBUG_DRIVER,
  1280. ("GEMSCR09!GDDKNT_09DeviceControl: ioControlCode=%lX status=%lX\n",
  1281. ioControlCode,status
  1282. )
  1283. );
  1284. return status;
  1285. }