update for HEAD-2003091401
[reactos.git] / drivers / dd / null / null.c
1 /* $Id$
2  *
3  * COPYRIGHT:        See COPYING in the top level directory
4  * PROJECT:          ReactOS kernel
5  * FILE:             services/null/null.c
6  * PURPOSE:          NULL device driver
7  * PROGRAMMER:       David Welch (welch@mcmail.com)
8  * UPDATE HISTORY:
9  *              13/08/1998: Created
10  *              29/04/2002: Fixed bugs, added zero-stream device
11  */
12
13 /* INCLUDES */
14 #include <ddk/ntddk.h>
15 #include "null.h"
16
17 /* OBJECTS */
18 static const NULL_EXTENSION nxNull = NullBitBucket;
19 static const NULL_EXTENSION nxZero = NullZeroStream;
20
21 /* FUNCTIONS */
22 NTSTATUS STDCALL
23 NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
24 {
25  PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
26  NTSTATUS nErrCode;
27  
28  nErrCode = STATUS_SUCCESS;
29
30  switch(piosStack->MajorFunction)
31  {
32   /* opening and closing handles to the device */
33   case IRP_MJ_CREATE:
34   case IRP_MJ_CLOSE:
35   {
36    break;
37   }
38
39   /* write data */
40   case IRP_MJ_WRITE:
41   {
42    switch(NULL_DEVICE_TYPE(DeviceObject))
43    {
44     case NullBitBucket:
45      Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
46      break;
47
48     case NullZeroStream:
49     default:
50      Irp->IoStatus.Information = 0;
51      nErrCode = STATUS_NOT_IMPLEMENTED;
52    }
53
54    break;
55   }
56
57   /* read data */
58   case IRP_MJ_READ:
59   {
60    switch(NULL_DEVICE_TYPE(DeviceObject))
61    {
62     case NullBitBucket:
63      Irp->IoStatus.Information = 0;
64      nErrCode = STATUS_END_OF_FILE;
65      break;
66
67     case NullZeroStream:
68      RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, piosStack->Parameters.Read.Length);
69      Irp->IoStatus.Information = piosStack->Parameters.Read.Length;
70      break;
71
72     default:
73      Irp->IoStatus.Information = 0;
74      nErrCode = STATUS_NOT_IMPLEMENTED;
75    }
76
77    break;
78   }
79
80   /* unsupported operations */
81   default:
82   {
83    nErrCode = STATUS_NOT_IMPLEMENTED;
84   }
85  }
86
87  Irp->IoStatus.Status = nErrCode;
88  IoCompleteRequest(Irp, IO_NO_INCREMENT);
89
90  return (nErrCode);
91 }
92
93 NTSTATUS STDCALL
94 NullUnload(PDRIVER_OBJECT DriverObject)
95 {
96  return(STATUS_SUCCESS);
97 }
98
99 NTSTATUS STDCALL 
100 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
101 {
102  PDEVICE_OBJECT pdoNullDevice;
103  PDEVICE_OBJECT pdoZeroDevice;
104  UNICODE_STRING wstrDeviceName;
105  NTSTATUS nErrCode;
106
107  /* register driver routines */
108  DriverObject->MajorFunction[IRP_MJ_CLOSE] = NullDispatch;
109  DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch;
110  DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch;
111  DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch;
112  /* DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NullDispatch; */
113  DriverObject->DriverUnload = NullUnload;
114
115  /* create null device */
116  RtlInitUnicodeStringFromLiteral(&wstrDeviceName, L"\\Device\\Null");
117
118  nErrCode = IoCreateDevice
119  (
120   DriverObject,
121   sizeof(NULL_EXTENSION),
122   &wstrDeviceName,
123   FILE_DEVICE_NULL,
124   0,
125   FALSE,
126   &pdoNullDevice
127  );
128
129  /* failure */
130  if(!NT_SUCCESS(nErrCode))
131  {
132   return (nErrCode);
133  }
134
135  pdoNullDevice->DeviceExtension = (PVOID)&nxNull;
136
137  /* create zero device */
138  RtlInitUnicodeStringFromLiteral(&wstrDeviceName, L"\\Device\\Zero");
139
140  nErrCode = IoCreateDevice
141  (
142   DriverObject,
143   sizeof(NULL_EXTENSION),
144   &wstrDeviceName,
145   FILE_DEVICE_NULL,
146   FILE_READ_ONLY_DEVICE, /* zero device is read-only */
147   FALSE,
148   &pdoZeroDevice
149  );
150
151  /* failure */
152  if(!NT_SUCCESS(nErrCode))
153  {
154   IoDeleteDevice(pdoNullDevice);
155   return (nErrCode);
156  }
157
158  pdoZeroDevice->DeviceExtension = (PVOID)&nxZero;
159  pdoZeroDevice->Flags |= DO_BUFFERED_IO;
160
161  return (nErrCode);
162 }
163
164 /* EOF */