Whamcloud - gitweb
7c9a1a1958bef7844fa78b98262c18466942adec
[fs/lustre-release.git] / lnet / tests / ping_cli / winnt-pingcli.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=4:tabstop=4:
3  *
4  * Copyright (C) 2002 Cluster File Systems, Inc.
5  *   Author: Matt Wu <mattwu@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #define DEBUG_SUBSYSTEM S_LNET
24
25 /*
26  *  Included Headers 
27  */
28
29
30 #include <libcfs/libcfs.h>
31
32
33 /* libcfs module init/exit routines */
34 DECLARE_INIT(init_libcfs_module);
35 DECLARE_EXIT(exit_libcfs_module);
36
37 /* portal module init/exit routines */
38 DECLARE_INIT(init_lnet);
39 DECLARE_EXIT(fini_lnet);
40
41 /* tdinal module init/exit routines */
42 DECLARE_INIT(ksocknal_module_init);
43 DECLARE_EXIT(ksocknal_module_fini);
44
45 /* pingcli module init/exit routines */
46 DECLARE_INIT(pingcli_init);
47 DECLARE_EXIT(pingcli_cleanup);
48
49
50 /* pingsrv module init/exit routines */
51 DECLARE_INIT(pingsrv_init);
52 DECLARE_EXIT(pingsrv_cleanup);
53
54 /*
55  * structure definitions
56  */
57
58
59 #define LUSTRE_PING_VERSION   0x00010000               /* ping srv/cli version: 0001.0000 */
60
61 #define LUSTRE_PING_DEVICE    L"\\Device\\LNET"     /* device object name */
62 #define LUSTRE_PING_SYMLNK    L"\\DosDevices\\LNET" /* user-visible name for the device*/
63
64 typedef struct _DEVICE_EXTENSION
65 {
66     BOOLEAN    bProcFS;
67
68 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
69
70
71 /*
72  *  global definitions
73  */
74
75 PDEVICE_OBJECT  PingObject = NULL;  /* ping device object */
76 PDEVICE_OBJECT  ProcObject = NULL;  /* procfs emulator device */
77
78
79 /*
80  *  common routines
81  */
82
83
84 //
85 // complete Irp request ...
86 //
87
88 NTSTATUS
89 UTCompleteIrp(
90     PIRP        Irp,
91     NTSTATUS    Status,
92     ULONG       Info
93     )
94 {
95     Irp->IoStatus.Status = Status;
96     Irp->IoStatus.Information = Info;
97     IoCompleteRequest(Irp,IO_NO_INCREMENT);
98
99     return Status;
100 }
101
102 //
103 //  Open/Create Device ...
104 //
105
106 NTSTATUS
107 UTCreate(
108     IN PDEVICE_OBJECT   DeviceObject,
109     IN PIRP             Irp
110     )
111 {
112     KdPrint(("UTCreate: DeviceCreate ...\n"));
113
114     return UTCompleteIrp(Irp,STATUS_SUCCESS,0);
115 }
116
117 //
118 // Close Devcie ...
119 //
120
121 NTSTATUS
122 UTClose(
123     IN PDEVICE_OBJECT   DeviceObject,
124     IN PIRP             Irp)
125 {
126     KdPrint(("UTClose: Device Closed.\n"));
127
128     return UTCompleteIrp(Irp, STATUS_SUCCESS, 0);
129
130     UNREFERENCED_PARAMETER(DeviceObject);
131 }
132
133
134
135 NTSTATUS
136 UTShutdown(
137     IN PDEVICE_OBJECT   DeviceObject,
138     IN PIRP             Irp
139     )
140 {
141     KdPrint(("UTShutdown: shuting TdiSock ...\n"));
142
143     return UTCompleteIrp(Irp, STATUS_SUCCESS, 0);
144
145     UNREFERENCED_PARAMETER(DeviceObject);
146 }
147
148 //
149 // driver frame Routines ...
150 //
151
152
153 NTSTATUS
154 UTDeviceControl(
155     IN PDEVICE_OBJECT   DeviceObject,
156     IN PIRP             Irp
157     )
158 {
159     NTSTATUS            Status = STATUS_INVALID_DEVICE_REQUEST;
160     PIO_STACK_LOCATION  IrpSp;
161
162     ULONG               ControlCode;
163     ULONG               InputLength;
164     ULONG               OutputLength;
165
166     PVOID               lpvInBuffer;
167
168     KdPrint(("UTDeviceControl: Device Ioctl ...\n"));
169
170     Irp->IoStatus.Information = 0;
171     IrpSp = IoGetCurrentIrpStackLocation(Irp);
172
173     ControlCode  = IrpSp->Parameters.DeviceIoControl.IoControlCode;
174     InputLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
175     OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
176     lpvInBuffer  = Irp->AssociatedIrp.SystemBuffer;
177
178     ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
179
180     switch (ControlCode)
181     {
182         case IOCTL_LIBCFS_VERSION:
183
184             *((ULONG *)lpvInBuffer) = (ULONG)(LUSTRE_PING_VERSION);
185             Irp->IoStatus.Information = sizeof(ULONG);
186             Status = STATUS_SUCCESS;
187             break;
188
189         default:
190             break;
191     }
192
193     Irp->IoStatus.Status = Status;
194
195     IoCompleteRequest(Irp, IO_NO_INCREMENT);
196
197     KdPrint(("UTDeviceControl: Device Ioctl returned.\n"));
198
199     return Status;
200 }
201
202 NTSTATUS
203 ProcCreate(
204     IN PDEVICE_OBJECT   DeviceObject,
205     IN PIRP             Irp
206     )
207 {
208     NTSTATUS                    Status;
209     PIO_STACK_LOCATION          IrpSp;
210
211     FILE_FULL_EA_INFORMATION *  ea;
212     cfs_file_t *                fp;
213
214     KdPrint(("ProcCreate: Proc device is being opened ...\n"));
215
216     IrpSp = IoGetCurrentIrpStackLocation(Irp);
217     ea = (PFILE_FULL_EA_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
218
219     if (!ea) {
220         Status = STATUS_INVALID_PARAMETER;
221     } else {
222         fp = lustre_open_file(&ea->EaName[0]);
223         if (!fp) {
224             Status = STATUS_OBJECT_NAME_NOT_FOUND;
225         } else {
226             IrpSp->FileObject->FsContext = fp;
227             IrpSp->FileObject->FsContext2 = fp->private_data;
228             Status = STATUS_SUCCESS;
229         }
230     }
231
232     return UTCompleteIrp(Irp, Status, 0);
233 }
234
235 //
236 // Close Devcie ...
237 //
238
239 NTSTATUS
240 ProcClose(
241     IN PDEVICE_OBJECT   DeviceObject,
242     IN PIRP             Irp)
243 {
244     PIO_STACK_LOCATION          IrpSp;
245
246     cfs_file_t *                fp;
247
248     KdPrint(("ProcClose: Proc device object is to be closed.\n"));
249
250     IrpSp = IoGetCurrentIrpStackLocation(Irp);
251
252     fp = (cfs_file_t *) IrpSp->FileObject->FsContext;
253
254     ASSERT(fp != NULL);
255     ASSERT(IrpSp->FileObject->FsContext2 == fp->private_data);
256
257     lustre_close_file(fp);
258
259     return UTCompleteIrp(Irp, STATUS_SUCCESS, 0);
260
261     UNREFERENCED_PARAMETER(DeviceObject);
262 }
263
264 /*
265  * proc frame routines
266  */
267
268 NTSTATUS
269 ProcDeviceControl(
270     IN PDEVICE_OBJECT   DeviceObject,
271     IN PIRP             Irp
272     )
273 {
274     NTSTATUS            Status = STATUS_INVALID_DEVICE_REQUEST;
275     PIO_STACK_LOCATION  IrpSp;
276
277     ULONG               ControlCode;
278     ULONG               InputLength;
279     ULONG               OutputLength;
280
281     PVOID               lpvInBuffer;
282
283     KdPrint(("ProcDeviceControl: Proc device ioctling ...\n"));
284
285     Irp->IoStatus.Information = 0;
286     IrpSp = IoGetCurrentIrpStackLocation(Irp);
287
288     ControlCode  = IrpSp->Parameters.DeviceIoControl.IoControlCode;
289     InputLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
290     OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
291     lpvInBuffer  = Irp->AssociatedIrp.SystemBuffer;
292
293     ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
294
295     switch (ControlCode)
296     {
297         case IOCTL_LIBCFS_VERSION:
298
299             *((ULONG *)lpvInBuffer) = (ULONG)(LUSTRE_PING_VERSION);
300             Irp->IoStatus.Information = sizeof(ULONG);
301
302             Status = STATUS_SUCCESS;
303
304             break;
305
306         case IOCTL_LIBCFS_ENTRY:
307         {
308             int rc = 0;
309             cfs_file_t * fp;
310
311             fp = (cfs_file_t *) IrpSp->FileObject->FsContext;
312
313             if (!fp) {
314                 rc = -EINVAL;
315             } else {
316                 rc = lustre_ioctl_file(fp, (PCFS_PROC_IOCTL) (lpvInBuffer));
317             }
318
319             if (rc == 0) {
320                 Irp->IoStatus.Information = InputLength;
321                 Status = STATUS_SUCCESS;
322             }
323         }    
324     }
325
326     Irp->IoStatus.Status = Status;
327
328     IoCompleteRequest(Irp, IO_NO_INCREMENT);
329
330     KdPrint(("ProcDeviceControl: Proc device ioctl returned with status = %xh.\n", Status));
331
332     return Status;
333 }
334
335
336
337 NTSTATUS
338 ProcReadWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
339 {
340     PIO_STACK_LOCATION  IrpSp;
341     NTSTATUS            Status;
342
343     cfs_file_t *        fp;
344     int                 rc;
345     PCHAR               buf;
346
347     IrpSp = IoGetCurrentIrpStackLocation(Irp);
348     if (Irp->MdlAddress) {
349         buf = MmGetSystemAddressForMdlSafe(
350                         Irp->MdlAddress,
351                         NormalPagePriority);
352     } else {
353         buf = Irp->AssociatedIrp.SystemBuffer;
354     }
355
356     if (buf == NULL) {
357         Status = STATUS_SUCCESS;
358         rc = 0;
359     } else {
360         fp = (cfs_file_t *) IrpSp->FileObject->FsContext;
361
362         if (!fp) {
363             Status = STATUS_INVALID_PARAMETER;
364             goto errorout;
365         }
366
367         if (IrpSp->MajorFunction == IRP_MJ_READ) {
368             rc = lustre_read_file(
369                     fp, IrpSp->Parameters.Read.ByteOffset.LowPart,
370                     IrpSp->Parameters.Read.Length, buf);
371         } else {
372             rc = lustre_write_file(
373                     fp, IrpSp->Parameters.Write.ByteOffset.LowPart,
374                     IrpSp->Parameters.Write.Length, buf);
375         }
376         if (rc < 0) {
377             cfs_enter_debugger();
378             Status = STATUS_UNSUCCESSFUL;
379         } else {
380             Status = STATUS_SUCCESS;
381         }
382     }
383
384  
385 errorout:
386     return UTCompleteIrp(Irp, Status, rc);
387 }
388
389
390 //
391 //  common dispatch routines
392 //
393
394 NTSTATUS
395 UTDispatchRequest(
396     IN PDEVICE_OBJECT DeviceObject,
397     IN PIRP           Irp
398     )
399 {
400     NTSTATUS            Status;
401     PIO_STACK_LOCATION  IrpSp;
402
403     Status = STATUS_INVALID_DEVICE_REQUEST;
404
405     __try {
406
407         IrpSp = IoGetCurrentIrpStackLocation(Irp);
408
409         switch (IrpSp->MajorFunction) {
410
411             case IRP_MJ_CREATE:
412                 if (DeviceObject == PingObject) {
413                     Status = UTCreate(DeviceObject, Irp);
414                 } else if (DeviceObject == ProcObject) {
415                     Status = ProcCreate(DeviceObject, Irp);
416                 }
417                 break;
418         
419             case IRP_MJ_CLOSE:
420                 if (DeviceObject == PingObject) {
421                     Status = UTClose(DeviceObject, Irp);
422                 } else if (DeviceObject == ProcObject) {
423                     Status = ProcClose(DeviceObject, Irp);
424                 }
425                 break;
426
427             case IRP_MJ_READ:
428             case IRP_MJ_WRITE:
429                 if (DeviceObject == ProcObject) {
430                     Status = ProcReadWrite(DeviceObject, Irp);
431                 }
432                 break;
433         
434             case IRP_MJ_DEVICE_CONTROL:
435                 if (DeviceObject == PingObject) {
436                     Status = UTDeviceControl(DeviceObject, Irp);
437                 } else if (DeviceObject == ProcObject) {
438                     Status = ProcDeviceControl(DeviceObject, Irp);
439                 }
440                 break;
441
442             case IRP_MJ_SHUTDOWN:
443                 Status = UTShutdown(DeviceObject, Irp);
444                 break;
445
446             default:
447
448                 KdPrint(("UTDispatchRequest: Major Function: %xh is not supported.\n",
449                            IrpSp->MajorFunction));
450                 UTCompleteIrp(Irp, Status, 0);
451                 break;
452         }
453     }
454
455     __finally {
456     }
457
458     return Status;
459 }
460
461 //
462 // create a device object and a dosdevice symbol link
463 //
464
465 PDEVICE_OBJECT
466 CreateDevice(
467     IN PDRIVER_OBJECT   DriverObject,
468     IN PWCHAR           DeviceName,
469     IN PWCHAR           SymlnkName,
470     IN BOOLEAN          bProcFS
471     )
472 {
473     NTSTATUS            Status;
474
475     UNICODE_STRING      NtDevName;
476     UNICODE_STRING      Win32DevName;
477
478     PDEVICE_EXTENSION   DeviceExtension;
479     PDEVICE_OBJECT      DeviceObject;
480
481     /* create the device object with the specified name */
482
483     RtlInitUnicodeString(&NtDevName, DeviceName);
484     
485     Status = IoCreateDevice(
486                     DriverObject,
487                     sizeof(DEVICE_EXTENSION),
488                     &NtDevName,
489                     FILE_DEVICE_UNKNOWN,
490                     0,
491                     FALSE,
492                     &DeviceObject );
493         
494     if (!NT_SUCCESS(Status)) {
495
496         cfs_enter_debugger();
497         return NULL;
498     }
499
500     /* create the symlink to make the device visible to user */
501
502     RtlInitUnicodeString(&Win32DevName, SymlnkName);
503         
504     Status = IoCreateSymbolicLink(&Win32DevName, &NtDevName);
505
506     if (!NT_SUCCESS(Status)) {
507
508         IoDeleteDevice(DeviceObject);
509         return NULL;
510     }
511
512     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceObjectExtension;
513     DeviceExtension->bProcFS = bProcFS;
514
515     DeviceObject->Flags |= DO_BUFFERED_IO;
516     DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
517
518     return DeviceObject;
519 }
520
521
522 //
523 // DriverEntry
524 //
525
526 NTSTATUS DriverEntry(
527     IN PDRIVER_OBJECT  DriverObject,
528     IN PUNICODE_STRING RegistryPath 
529     )
530 {
531     KdPrint(("Lustre ping test: Build Time: " __DATE__ " " __TIME__ "\n"));
532     KdPrint(("Lustre ping test: DriverEntry ... \n"));
533
534     /* initialize libcfs module */
535     if (module_init_libcfs_module() != 0) {
536         KdPrint(("ping: error initialize module: libcfs ...\n"));
537         goto errorout;
538     }
539
540     /* initialize lnet module */
541     if (module_init_lnet() != 0) {
542         module_exit_libcfs_module();
543         KdPrint(("ping: error initialize module: lnet ...\n"));
544         goto errorout;
545     }
546
547     /* initialize tdinal module */
548     if (module_ksocknal_module_init() != 0) {
549         module_fini_lnet();
550         module_exit_libcfs_module();
551         KdPrint(("ping: error initialize module: tdilnd ...\n"));
552         goto errorout;
553     }
554
555 #if defined(LUSTRE_PING_CLI)
556     /* initialize pingcli module */
557     if (module_pingcli_init() != 0) {
558         module_ksocknal_module_fini();
559         module_fini_lnet();
560         module_exit_libcfs_module();
561         KdPrint(("ping: error initialize module: pingcli ...\n"));
562         goto errorout;
563     }
564 #endif
565
566 #if defined(LUSTRE_PING_SRV)
567     /* initialize pingsrv module */
568     if (module_pingsrv_init() != 0) {
569         module_ksocknal_module_fini();
570         module_fini_lnet();
571         module_exit_libcfs_module();
572         KdPrint(("ping: error initialize module: pingsrv ...\n"));
573         goto errorout;
574     }
575 #endif
576
577     /* create the ping device object */
578     PingObject = CreateDevice(
579                         DriverObject,
580                         LUSTRE_PING_DEVICE,
581                         LUSTRE_PING_SYMLNK,
582                         FALSE );
583     if (!PingObject) {
584 #if defined(LUSTRE_PING_CLI)
585         module_pingcli_cleanup();
586 #endif
587 #if defined(LUSTRE_PING_SRV)
588         module_pingsrv_cleanup();
589 #endif
590         module_ksocknal_module_fini();
591         module_fini_lnet();
592         module_exit_libcfs_module();
593
594         return STATUS_INSUFFICIENT_RESOURCES;
595     }
596
597     /* create the libcfs proc fs emultor device object */
598     ProcObject  = CreateDevice(
599                         DriverObject,
600                         LUSTRE_PROC_DEVICE,
601                         LUSTRE_PROC_SYMLNK,
602                         TRUE );
603     if (!ProcObject) {
604
605         IoDeleteDevice(PingObject);
606 #if defined(LUSTRE_PING_CLI)
607         module_pingcli_cleanup();
608 #endif
609 #if defined(LUSTRE_PING_SRV)
610         module_pingsrv_cleanup();
611 #endif
612         module_ksocknal_module_fini();
613         module_fini_lnet();
614         module_exit_libcfs_module();
615         return STATUS_INSUFFICIENT_RESOURCES;
616     }
617
618     /* initialize the driver callback routines */
619
620     DriverObject->MajorFunction[IRP_MJ_CREATE]          = UTDispatchRequest;
621     DriverObject->MajorFunction[IRP_MJ_CLOSE]           = UTDispatchRequest;
622     DriverObject->MajorFunction[IRP_MJ_READ]            = UTDispatchRequest;
623     DriverObject->MajorFunction[IRP_MJ_WRITE]           = UTDispatchRequest;
624     DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]        = UTDispatchRequest;
625     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = UTDispatchRequest;
626
627     return STATUS_SUCCESS;
628
629 errorout:
630
631     cfs_enter_debugger();
632
633     return STATUS_UNSUCCESSFUL;
634 }