xref: /reactos/drivers/filesystems/msfs/finfo.c (revision 50cf16b3)
1 /*
2  * COPYRIGHT:  See COPYING in the top level directory
3  * PROJECT:    ReactOS kernel
4  * FILE:       drivers/filesystems/msfs/finfo.c
5  * PURPOSE:    Mailslot filesystem
6  * PROGRAMMER: Eric Kohl
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "msfs.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 #undef MAILSLOT_NO_MESSAGE
17 #undef MAILSLOT_WAIT_FOREVER
18 #define MAILSLOT_NO_MESSAGE   MAXULONG
19 #define MAILSLOT_WAIT_FOREVER MAXULONG
20 
21 /* FUNCTIONS *****************************************************************/
22 
23 static NTSTATUS
24 MsfsQueryMailslotInformation(PMSFS_FCB Fcb,
25                              PFILE_MAILSLOT_QUERY_INFORMATION Buffer,
26                              PULONG BufferLength)
27 {
28     KIRQL oldIrql;
29 
30     if (*BufferLength < sizeof(FILE_MAILSLOT_QUERY_INFORMATION))
31         return STATUS_BUFFER_OVERFLOW;
32 
33     Buffer->MaximumMessageSize = Fcb->MaxMessageSize;
34     Buffer->ReadTimeout = Fcb->TimeOut;
35 
36     KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql);
37     Buffer->MessagesAvailable = Fcb->MessageCount;
38     if (Fcb->MessageCount == 0)
39     {
40         Buffer->NextMessageSize = MAILSLOT_NO_MESSAGE;
41     }
42     else
43     {
44         PMSFS_MESSAGE Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink,
45                                                   MSFS_MESSAGE,
46                                                   MessageListEntry);
47         Buffer->NextMessageSize = Message->Size;
48     }
49     KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql);
50 
51     *BufferLength -= sizeof(FILE_MAILSLOT_QUERY_INFORMATION);
52 
53     return STATUS_SUCCESS;
54 }
55 
56 
57 static NTSTATUS
58 MsfsSetMailslotInformation(PMSFS_FCB Fcb,
59                            PFILE_MAILSLOT_SET_INFORMATION Buffer,
60                            PULONG BufferLength)
61 {
62     if (*BufferLength < sizeof(FILE_MAILSLOT_SET_INFORMATION))
63         return STATUS_BUFFER_OVERFLOW;
64 
65     Fcb->TimeOut = *Buffer->ReadTimeout;
66 
67     return STATUS_SUCCESS;
68 }
69 
70 
71 NTSTATUS DEFAULTAPI
72 MsfsQueryInformation(PDEVICE_OBJECT DeviceObject,
73                      PIRP Irp)
74 {
75     PIO_STACK_LOCATION IoStack;
76     FILE_INFORMATION_CLASS FileInformationClass;
77     PFILE_OBJECT FileObject;
78     PMSFS_FCB Fcb;
79     PMSFS_CCB Ccb;
80     PVOID SystemBuffer;
81     ULONG BufferLength;
82     NTSTATUS Status;
83 
84     DPRINT("MsfsQueryInformation(DeviceObject %p Irp %p)\n",
85            DeviceObject, Irp);
86 
87     IoStack = IoGetCurrentIrpStackLocation (Irp);
88     FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
89     FileObject = IoStack->FileObject;
90     Fcb = (PMSFS_FCB)FileObject->FsContext;
91     Ccb = (PMSFS_CCB)FileObject->FsContext2;
92 
93     DPRINT("Mailslot name: %wZ\n", &Fcb->Name);
94 
95     /* querying information is not permitted on client side */
96     if (Fcb->ServerCcb != Ccb)
97     {
98         Status = STATUS_ACCESS_DENIED;
99 
100         Irp->IoStatus.Status = Status;
101         Irp->IoStatus.Information = 0;
102 
103         IoCompleteRequest(Irp, IO_NO_INCREMENT);
104 
105         return Status;
106     }
107 
108     SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
109     BufferLength = IoStack->Parameters.QueryFile.Length;
110 
111     switch (FileInformationClass)
112     {
113     case FileMailslotQueryInformation:
114         Status = MsfsQueryMailslotInformation(Fcb,
115                                               SystemBuffer,
116                                               &BufferLength);
117         break;
118 
119     default:
120         Status = STATUS_NOT_IMPLEMENTED;
121     }
122 
123     Irp->IoStatus.Status = Status;
124     if (NT_SUCCESS(Status))
125         Irp->IoStatus.Information =
126              IoStack->Parameters.QueryFile.Length - BufferLength;
127     else
128         Irp->IoStatus.Information = 0;
129     IoCompleteRequest(Irp, IO_NO_INCREMENT);
130 
131     return Status;
132 }
133 
134 
135 NTSTATUS DEFAULTAPI
136 MsfsSetInformation(PDEVICE_OBJECT DeviceObject,
137                    PIRP Irp)
138 {
139     PIO_STACK_LOCATION IoStack;
140     FILE_INFORMATION_CLASS FileInformationClass;
141     PFILE_OBJECT FileObject;
142     PMSFS_FCB Fcb;
143     PMSFS_CCB Ccb;
144     PVOID SystemBuffer;
145     ULONG BufferLength;
146     NTSTATUS Status;
147 
148     DPRINT("MsfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
149 
150     IoStack = IoGetCurrentIrpStackLocation (Irp);
151     FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
152     FileObject = IoStack->FileObject;
153     Fcb = (PMSFS_FCB)FileObject->FsContext;
154     Ccb = (PMSFS_CCB)FileObject->FsContext2;
155 
156     DPRINT("Mailslot name: %wZ\n", &Fcb->Name);
157 
158     /* setting information is not permitted on client side */
159     if (Fcb->ServerCcb != Ccb)
160     {
161         Status = STATUS_ACCESS_DENIED;
162 
163         Irp->IoStatus.Status = Status;
164         Irp->IoStatus.Information = 0;
165 
166         IoCompleteRequest(Irp, IO_NO_INCREMENT);
167 
168         return Status;
169     }
170 
171     SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
172     BufferLength = IoStack->Parameters.QueryFile.Length;
173 
174     DPRINT("FileInformationClass %d\n", FileInformationClass);
175     DPRINT("SystemBuffer %p\n", SystemBuffer);
176 
177     switch (FileInformationClass)
178     {
179     case FileMailslotSetInformation:
180         Status = MsfsSetMailslotInformation(Fcb,
181                                             SystemBuffer,
182                                             &BufferLength);
183         break;
184 
185      default:
186         Status = STATUS_NOT_IMPLEMENTED;
187     }
188 
189     Irp->IoStatus.Status = Status;
190     Irp->IoStatus.Information = 0;
191     IoCompleteRequest(Irp, IO_NO_INCREMENT);
192 
193     return Status;
194 }
195 
196 /* EOF */
197