/*++ Copyright (c) 1998-2000 Microsoft Corporation Module Name: drdev Abstract: This module defines the parent for the client-side RDP device redirection "device" class hierarchy, DrDevice. Author: Tad Brockway 3/23/99 Revision History: --*/ #include #define TRC_FILE "DrDev" #include "drdev.h" #include "proc.h" #include "drconfig.h" #include "utl.h" #include "drfile.h" #include "drobjmgr.h" #ifdef OS_WINCE #include "filemgr.h" #endif /////////////////////////////////////////////////////////////// // // DrDevice Methods // // DrDevice::DrDevice(ProcObj *processObject, ULONG deviceID) /*++ Routine Description: Constructor for the DrDevice class. Arguments: processObject - Parent process object. id - Unique device ID. Return Value: None --*/ { DC_BEGIN_FN("DrDevice::DrDevice"); ASSERT(processObject != NULL); _deviceID = deviceID; _processObject = processObject; _deviceChange = DEVICENEW; _FileMgr = NULL; // // Not valid until initialized. // SetValid(FALSE); DC_END_FN(); } DrDevice::~DrDevice() /*++ Routine Description: Destructor for the DrDevice class. Arguments: None Return Value: None --*/ { DrFile *pFileObj; DC_BEGIN_FN("DrDevice::~DrDevice"); // // Clean up the file management list. // if (_FileMgr != NULL) { _FileMgr->Lock(); while ((pFileObj = _FileMgr->GetFirstObject()) != NULL) { pFileObj->Close(); _FileMgr->RemoveObject(pFileObj->GetID()); pFileObj->Release(); } _FileMgr->Unlock(); delete _FileMgr; } DC_END_FN(); } DWORD DrDevice::Initialize() /*++ Routine Description: Initialize. Arguments: pIoRequestPacket - IO request from server. Return Value: None --*/ { DWORD result; DC_BEGIN_FN("DrDevice::Initialize"); _FileMgr = new DrFileMgr(); if (_FileMgr == NULL) { TRC_ERR((TB, L"Error allocating file mgr.")); result = ERROR_NOT_ENOUGH_MEMORY; goto CLEANUPANDEXIT; } result = _FileMgr->Initialize(); if (result != ERROR_SUCCESS) { delete _FileMgr; _FileMgr = NULL; goto CLEANUPANDEXIT; } SetValid(TRUE); CLEANUPANDEXIT: DC_END_FN(); return result; } VOID DrDevice::ProcessIORequest( IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket, IN UINT32 packetLen ) /*++ Routine Description: Handle an IO request from the server. Arguments: pIoRequestPacket - IO request from server. packetLen - length of the packet Return Value: None --*/ { PRDPDR_DEVICE_IOREQUEST pIORequest; DC_BEGIN_FN("DrDevice::ProcessIORequest"); // // Make sure we are valid. // ASSERT(IsValid()); if (!IsValid()) { DefaultIORequestMsgHandle(pIoRequestPacket, STATUS_UNSUCCESSFUL); DC_END_FN(); return; } // // Dispatch the request. // pIORequest = &pIoRequestPacket->IoRequest; switch (pIORequest->MajorFunction) { case IRP_MJ_CREATE : MsgIrpCreate(pIoRequestPacket, packetLen); break; case IRP_MJ_CLEANUP : MsgIrpCleanup(pIoRequestPacket, packetLen); break; case IRP_MJ_CLOSE : MsgIrpClose(pIoRequestPacket, packetLen); break; case IRP_MJ_READ : MsgIrpRead(pIoRequestPacket, packetLen); break; case IRP_MJ_WRITE : MsgIrpWrite(pIoRequestPacket, packetLen); break; case IRP_MJ_FLUSH_BUFFERS : MsgIrpFlushBuffers(pIoRequestPacket, packetLen); break; case IRP_MJ_SHUTDOWN : MsgIrpShutdown(pIoRequestPacket, packetLen); break; case IRP_MJ_DEVICE_CONTROL : MsgIrpDeviceControl(pIoRequestPacket, packetLen); break; case IRP_MJ_LOCK_CONTROL : MsgIrpLockControl(pIoRequestPacket, packetLen); break; case IRP_MJ_INTERNAL_DEVICE_CONTROL : MsgIrpInternalDeviceControl(pIoRequestPacket, packetLen); break; case IRP_MJ_DIRECTORY_CONTROL : MsgIrpDirectoryControl(pIoRequestPacket, packetLen); break; case IRP_MJ_QUERY_VOLUME_INFORMATION : MsgIrpQueryVolumeInfo(pIoRequestPacket, packetLen); break; case IRP_MJ_SET_VOLUME_INFORMATION : MsgIrpSetVolumeInfo(pIoRequestPacket, packetLen); break; case IRP_MJ_QUERY_INFORMATION : MsgIrpQueryFileInfo(pIoRequestPacket, packetLen); break; case IRP_MJ_SET_INFORMATION : MsgIrpSetFileInfo(pIoRequestPacket, packetLen); break; case IRP_MJ_QUERY_SECURITY : MsgIrpQuerySdInfo(pIoRequestPacket, packetLen); break; case IRP_MJ_SET_SECURITY : MsgIrpSetSdInfo(pIoRequestPacket, packetLen); break; default: TRC_ALT((TB, _T("Unknown MajorFunction, %ld."), pIORequest->MajorFunction )); DefaultIORequestMsgHandle(pIoRequestPacket, STATUS_UNSUCCESSFUL); break; } DC_END_FN(); } VOID DrDevice::DefaultIORequestMsgHandle( IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket, IN NTSTATUS serverReturnStatus ) /*++ Routine Description: Default IO Request Handling. Arguments: pIoRequestPacket - IO request from server. serverReturnStatus - NT error status to return to server. Return Value: None --*/ { PRDPDR_DEVICE_IOREQUEST pIoRequest; PRDPDR_IOCOMPLETION_PACKET pReplyPacket = NULL; ULONG ulReplyPacketSize = 0; DC_BEGIN_FN("DrDevice::DefaultIORequestMsgHandle entered"); // // Get IO request pointer. // pIoRequest = &pIoRequestPacket->IoRequest; // // Calculate the size of the reply packet, based on the type // of request. // if ((serverReturnStatus != STATUS_SUCCESS) && (pIoRequest->MajorFunction != IRP_MJ_DEVICE_CONTROL)) { ulReplyPacketSize = sizeof(RDPDR_IOCOMPLETION_PACKET); } else { pIoRequest->Parameters.DeviceIoControl.OutputBufferLength = 0; ulReplyPacketSize = DR_IOCTL_REPLYBUFSIZE(pIoRequest); } // // Allocate reply buffer. // pReplyPacket = DrUTL_AllocIOCompletePacket(pIoRequestPacket, ulReplyPacketSize) ; if (pReplyPacket != NULL) { pReplyPacket->IoCompletion.IoStatus = serverReturnStatus; ProcessObject()->GetVCMgr().ChannelWrite( (PVOID)pReplyPacket, (UINT)ulReplyPacketSize ); } else { TRC_ERR((TB, _T("Failed to alloc %ld bytes."),ulReplyPacketSize)); } Cleanup: // // Clean up the request packet. // delete pIoRequestPacket; DC_END_FN(); }