Leaked source code of windows server 2003
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.

333 lines
7.3 KiB

  1. #include "timestmp.h"
  2. #define FRIENDLY_NAME L"\\DosDevices\\Timestmp"
  3. NTSTATUS
  4. IoctlInitialize(
  5. PDRIVER_OBJECT DriverObject
  6. )
  7. /*++
  8. Routine Description:
  9. Perform initialization
  10. Arguments:
  11. DriverObject - pointer to DriverObject from DriverEntry
  12. InitShutdownMask - pointer to mask used to indicate which events have been
  13. successfully init'ed
  14. Return Value:
  15. STATUS_SUCCESS if everything worked ok
  16. --*/
  17. {
  18. NTSTATUS Status;
  19. UINT FuncIndex;
  20. //
  21. // Initialize the driver object's entry points
  22. //
  23. DriverObject->FastIoDispatch = NULL;
  24. for (FuncIndex = 0; FuncIndex <= IRP_MJ_MAXIMUM_FUNCTION; FuncIndex++) {
  25. DriverObject->MajorFunction[FuncIndex] = IoctlHandler;
  26. }
  27. RtlInitUnicodeString(&TimestmpDriverName,
  28. L"\\Device\\Timestmp");
  29. Status = IoCreateDevice(DriverObject,
  30. 0,
  31. &TimestmpDriverName,
  32. FILE_DEVICE_NETWORK,
  33. FILE_DEVICE_SECURE_OPEN,
  34. FALSE,
  35. &TimestmpDeviceObject);
  36. if ( NT_SUCCESS( Status )) {
  37. // Now create a symbolic link so that apps can open with createfile.
  38. DbgPrint("IoCreateDevice SUCCESS!\n");
  39. RtlInitUnicodeString (&symbolicLinkName, FRIENDLY_NAME);
  40. DbgPrint("The DeviceName(%ws) and FriendlyName(%ws) are OK\n", TimestmpDriverName, symbolicLinkName);
  41. Status = IoCreateSymbolicLink(&symbolicLinkName, &TimestmpDriverName);
  42. if (!NT_SUCCESS (Status)) {
  43. DbgPrint("Failed to create symbolic link: %lx\n", Status);
  44. //IoDeleteDevice(TimestmpDeviceObject);
  45. return STATUS_UNSUCCESSFUL;
  46. }
  47. TimestmpDeviceObject->Flags |= DO_BUFFERED_IO;
  48. } else {
  49. DbgPrint("IoCreateDevice failed. Status = %x\n", Status);
  50. TimestmpDeviceObject = NULL;
  51. }
  52. return Status;
  53. }
  54. NTSTATUS
  55. IoctlHandler(
  56. IN PDEVICE_OBJECT DeviceObject,
  57. IN PIRP Irp
  58. )
  59. /*++
  60. Routine Description:
  61. Process the IRPs sent to this device.
  62. Arguments:
  63. DeviceObject - pointer to a device object
  64. Irp - pointer to an I/O Request Packet
  65. Return Value:
  66. None
  67. --*/
  68. {
  69. PIO_STACK_LOCATION irpStack;
  70. PVOID ioBuffer;
  71. ULONG inputBufferLength;
  72. ULONG outputBufferLength;
  73. ULONG ioControlCode;
  74. UCHAR saveControlFlags;
  75. NTSTATUS Status = STATUS_SUCCESS;
  76. PPORT_ENTRY pPortEntry;
  77. PLIST_ENTRY ListEntry;
  78. USHORT Port = 0;
  79. PAGED_CODE();
  80. //
  81. // Init to default settings- we only expect 1 type of
  82. // IOCTL to roll through here, all others an error.
  83. //
  84. Irp->IoStatus.Status = STATUS_SUCCESS;
  85. Irp->IoStatus.Information = 0;
  86. //
  87. // Get a pointer to the current location in the Irp. This is where
  88. // the function codes and parameters are located.
  89. //
  90. irpStack = IoGetCurrentIrpStackLocation(Irp);
  91. //
  92. // Get the pointer to the input/output buffer and it's length
  93. //
  94. ioBuffer = Irp->AssociatedIrp.SystemBuffer;
  95. inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  96. outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  97. ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
  98. saveControlFlags = irpStack->Control;
  99. switch (irpStack->MajorFunction) {
  100. case IRP_MJ_CREATE:
  101. DbgPrint("CREATE\n");
  102. break;
  103. case IRP_MJ_READ:
  104. DbgPrint("READ\n");
  105. break;
  106. case IRP_MJ_CLOSE:
  107. DbgPrint("CLOSE\n");
  108. DbgPrint("FileObject %X\n", irpStack->FileObject);
  109. RemoveAllPortsForFileObject(irpStack->FileObject);
  110. //
  111. // make sure we clean all the objects for this particular
  112. // file object, since it's closing right now.
  113. //
  114. break;
  115. case IRP_MJ_CLEANUP:
  116. DbgPrint("CLEANUP\n");
  117. break;
  118. case IRP_MJ_SHUTDOWN:
  119. DbgPrint("Shutdown\n");
  120. break;
  121. case IRP_MJ_DEVICE_CONTROL:
  122. DbgPrint("The ioBuffer is %X and the contents are %d\n", ioBuffer, Port);
  123. Port = *(USHORT *)ioBuffer;
  124. DbgPrint("The Port number being added is %d\n", Port);
  125. switch (ioControlCode) {
  126. case IOCTL_TIMESTMP_REGISTER_PORT:
  127. DbgPrint("Register\n");
  128. //
  129. // Grab the PortList lock and Insert the new port.
  130. //
  131. NdisAcquireSpinLock(&PortSpinLock);
  132. pPortEntry = ExAllocatePoolWithTag(NonPagedPool,sizeof(PORT_ENTRY),'pmST');
  133. if (pPortEntry) {
  134. InitializeListHead(&pPortEntry->Linkage);
  135. pPortEntry->Port = Port;
  136. pPortEntry->FileObject = irpStack->FileObject;
  137. InsertHeadList(&PortList, &pPortEntry->Linkage);
  138. DbgPrint("Successfully inserted %d\n", Port);
  139. } else {
  140. DbgPrint("Couldn't allocate memory\n");
  141. }
  142. NdisReleaseSpinLock(&PortSpinLock);
  143. break;
  144. case IOCTL_TIMESTMP_DEREGISTER_PORT:
  145. DbgPrint("DERegister\n");
  146. //
  147. // Grab the PortList lock and REMOVE the new port.
  148. //
  149. NdisAcquireSpinLock(&PortSpinLock);
  150. pPortEntry = CheckInPortList(Port);
  151. if (pPortEntry) {
  152. RemoveEntryList(&pPortEntry->Linkage);
  153. ExFreePool(pPortEntry);
  154. DbgPrint("Successfully removed/freed %d\n", Port);
  155. } else {
  156. DbgPrint("Couldn't find port %d\n", Port);
  157. }
  158. NdisReleaseSpinLock(&PortSpinLock);
  159. break;
  160. } // switch (ioControlCode)
  161. break;
  162. default:
  163. DbgPrint("GPCIoctl: Unknown IRP major function = %08X\n", irpStack->MajorFunction);
  164. Status = STATUS_UNSUCCESSFUL;
  165. break;
  166. }
  167. DbgPrint("GPCIoctl: Status=0x%X, IRP=0x%X, outSize=%d\n", Status, (ULONG_PTR)Irp, outputBufferLength);
  168. if (Status != STATUS_PENDING) {
  169. //
  170. // IRP completed and it's not Pending, we need to restore the Control flags,
  171. // since it might have been marked as Pending before...
  172. //
  173. irpStack->Control = saveControlFlags;
  174. Irp->IoStatus.Status = Status;
  175. Irp->IoStatus.Information = outputBufferLength;
  176. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  177. }
  178. return Status;
  179. } // GPCIoctl
  180. VOID
  181. IoctlCleanup(
  182. )
  183. /*++
  184. Routine Description:
  185. Cleanup code for Initialize
  186. Arguments:
  187. ShutdownMask - mask indicating which functions need to be cleaned up
  188. Return Value:
  189. None
  190. --*/
  191. {
  192. IoDeleteDevice( TimestmpDeviceObject );
  193. }
  194. VOID
  195. RemoveAllPortsForFileObject(
  196. PFILE_OBJECT FileObject
  197. )
  198. {
  199. PLIST_ENTRY ListEntry;
  200. PPORT_ENTRY pPortEntry;
  201. NdisAcquireSpinLock(&PortSpinLock);
  202. ListEntry = PortList.Flink;
  203. while (ListEntry != &PortList) {
  204. pPortEntry = CONTAINING_RECORD(ListEntry, PORT_ENTRY, Linkage);
  205. ListEntry = ListEntry->Flink;
  206. if (FileObject == pPortEntry->FileObject) {
  207. DbgPrint("Deleting Port%d for FileObject0x%X\n", pPortEntry->Port, pPortEntry->FileObject);
  208. RemoveEntryList(&pPortEntry->Linkage);
  209. ExFreePool(pPortEntry);
  210. }
  211. }
  212. NdisReleaseSpinLock(&PortSpinLock);
  213. }