/****************************************************************************/ // ntdd.c // // Standard NT driver initialization, for inclusion in each of the TS // stack drivers. // // Copyright (C) 1997-1999 Microsoft Corp. /****************************************************************************/ #include "precomp.h" #pragma hdrstop #define DEVICE_NAME_PREFIX L"\\Device\\" // // Global data // PDEVICE_OBJECT DrvDeviceObject; // // External references // // This is the name of the WD/TD/PD module we are initializing as. extern const PWCHAR ModuleName; // Global code page caching data to be initialized and freed in asmint.c. extern FAST_MUTEX fmCodePage; extern ULONG LastCodePageTranslated; extern PVOID LastNlsTableBuffer; extern UINT NlsTableUseCount; // This is the stack driver module entry point defined in ntos\citrix\inc\sdapi.h NTSTATUS _stdcall ModuleEntry( IN OUT PSDCONTEXT pSdContext, IN BOOLEAN bLoad ); // // Forward refrences // VOID DrvUnload( PDRIVER_OBJECT ); NTSTATUS DrvDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: Standard NT driver entry routine. Arguments: DriverObject - NT passed driver object RegistryPath - Path to driver specific registry entry Return Value: NTSTATUS code. Environment: Kernel mode, DDK --*/ { ULONG i; NTSTATUS Status; UNICODE_STRING DeviceName; PWCHAR NameBuffer; ULONG NameSize; PAGED_CODE( ); NameSize = sizeof(DEVICE_NAME_PREFIX) + sizeof(WCHAR); NameSize += (wcslen(ModuleName) * sizeof(WCHAR)); NameBuffer = ExAllocatePool( NonPagedPool, NameSize ); if( NameBuffer == NULL ) { return( STATUS_INSUFFICIENT_RESOURCES ); } wcscpy( NameBuffer, DEVICE_NAME_PREFIX ); wcscat( NameBuffer, ModuleName ); RtlInitUnicodeString( &DeviceName, NameBuffer ); Status = IoCreateDevice( DriverObject, 0, // No DeviceExtension &DeviceName, FILE_DEVICE_TERMSRV, 0, FALSE, &DrvDeviceObject ); if( !NT_SUCCESS(Status) ) { ExFreePool( NameBuffer ); return( Status ); } DriverObject->DriverUnload = DrvUnload; DriverObject->FastIoDispatch = NULL; for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DrvDispatch; } // Init code page handling info from asmint.c. ExInitializeFastMutex(&fmCodePage); LastCodePageTranslated = 0; LastNlsTableBuffer = NULL; NlsTableUseCount = 0; DrvDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; ExFreePool( NameBuffer ); return( Status ); } VOID DrvUnload( IN PDRIVER_OBJECT DriverObject ) /*++ Routine Description: Driver unload routine. Arguments: DriverObject - Driver object being unloaded. Return Value: None. Environment: Kernel mode, DDK --*/ { PAGED_CODE( ); // Free remaining code page data on exit, if it exists. if (LastNlsTableBuffer != NULL) { ExFreePool(LastNlsTableBuffer); LastNlsTableBuffer = NULL; } IoDeleteDevice( DrvDeviceObject ); return; } NTSTATUS DrvDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This is the dispatch routine for the driver. Arguments: DeviceObject - Pointer to device object for target device Irp - Pointer to I/O request packet Return Value: NTSTATUS -- Indicates whether the request was successfully queued. Environment: Kernel mode, DDK --*/ { PIO_STACK_LOCATION irpSp; KIRQL saveIrql; NTSTATUS Status; PSD_MODULE_INIT pmi; DeviceObject; // prevent compiler warnings irpSp = IoGetCurrentIrpStackLocation( Irp ); switch ( irpSp->MajorFunction ) { case IRP_MJ_CREATE: if( Irp->RequestorMode != KernelMode ) { Status = STATUS_ACCESS_DENIED; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return( Status ); } Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return Status; case IRP_MJ_INTERNAL_DEVICE_CONTROL: if( Irp->RequestorMode != KernelMode ) { Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return( Status ); } if( irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_SD_MODULE_INIT ) { Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return( Status ); } if( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SD_MODULE_INIT) ) { Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return( Status ); } // Return the SD module entry point. pmi = (PSD_MODULE_INIT)Irp->UserBuffer; pmi->SdLoadProc = ModuleEntry; Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(SD_MODULE_INIT); Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return Status; case IRP_MJ_CLEANUP: Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return Status; case IRP_MJ_CLOSE: Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, 0 ); return Status; default: Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; IoCompleteRequest( Irp, 0 ); return STATUS_NOT_IMPLEMENTED; } }