?? iomgr.cpp
字號:
//***********************************************************************/
// Author : Garry
// Original Date : May,02 2005
// Module Name : iomgr.cpp
// Module Funciton :
// This module countains the implementation code of
// I/O Manager.
// Last modified Author :
// Last modified Date :
// Last modified Content :
// 1.
// 2.
// Lines number :
//***********************************************************************/
#ifndef __STDAFX_H__
#include "..\INCLUDE\StdAfx.h"
#endif
//
//In front of this file,we implement three call back routines first,these three
//call back routines are called by device driver(s) to report some events to IOManager.
//These three routines are members of DRCB object,i.e,their base addresses are countained
//in DRCB object.
//The first routine is WaitForCompletion,this routine is called when device driver(s)
//submit a device operation transaction,such as READ or WRITE,and to wait the operation
//over,in this situation,device driver(s) calls this this routine,put the current kernel
//thread to BLOCKED queue.
//The second routine is OnCompletion,this routine is called when device request operation
//over,to indicate the IOManager this event,and wakeup the kernel thread which is blocked
//in WaitForCompletion routine.
//The third routine is OnCancel,which is called when an IO operation is canceled.
//
//
//The implementation of WaitForCompletion.
//This routine does the following:
// 1. Check the validation of parameter(s);
// 2. Block the current kernel thread.
//
static DWORD WaitForCompletion(__COMMON_OBJECT* lpThis)
{
__DRCB* lpDrcb = NULL;
__EVENT* lpEvent = NULL;
if(NULL == lpThis) //Invalid parameter.
return 0L;
lpDrcb = (__DRCB*)lpThis;
lpEvent = lpDrcb->lpSynObject;
lpEvent->WaitForThisObject((__COMMON_OBJECT*)lpEvent); //Block the current kernel thread.
return 1L;
}
//
//The implementation of OnCompletion.
//This routine does the following:
// 1. Check the parameter's validation;
// 2. Wakeup the kernel thread who waiting for the current device operation.
//
static DWORD OnCompletion(__COMMON_OBJECT* lpThis)
{
__EVENT* lpEvent = NULL;
if(NULL == lpThis)
return 0L;
lpEvent = ((__DRCB*)lpThis)->lpSynObject;
lpEvent->SetEvent((__COMMON_OBJECT*)lpEvent); //Wakeup kernel thread.
return 1L;
}
//
//The implementation of OnCancel.
//This routine does the following:
// 1.
//
static DWORD OnCancel(__COMMON_OBJECT* lpThis)
{
if(NULL == lpThis) //Parameter check.
return 0L;
return 1L;
}
//
//The Initialize routine and UnInitialize routine of DRCB.
//
BOOL DrcbInitialize(__COMMON_OBJECT* lpThis)
{
__EVENT* lpSynObject = NULL;
__DRCB* lpDrcb = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis)
return FALSE;
lpDrcb = (__DRCB*)lpThis;
lpSynObject = (__EVENT*)ObjectManager.CreateObject(
&ObjectManager,
NULL,
OBJECT_TYPE_EVENT);
if(NULL == lpSynObject) //Failed to create event object.
return FALSE;
if(!lpSynObject->Initialize((__COMMON_OBJECT*)lpSynObject)) //Failed to initialize.
{
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpSynObject);
return FALSE;
}
lpDrcb->lpSynObject = lpSynObject;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpDrcb->lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
lpDrcb->dwDrcbFlag = 0L;
lpDrcb->dwStatus = DRCB_STATUS_INITIALIZED;
lpDrcb->dwRequestMode = 0L;
lpDrcb->dwCtrlCommand = 0L;
lpDrcb->dwOutputLen = 0L;
lpDrcb->lpOutputBuffer = NULL;
lpDrcb->dwInputLen = 0L;
lpDrcb->lpInputBuffer = NULL;
lpDrcb->lpNext = NULL;
lpDrcb->lpPrev = NULL;
lpDrcb->WaitForCompletion = NULL;
lpDrcb->OnCompletion = NULL;
lpDrcb->OnCancel = NULL;
lpDrcb->lpDrcbExtension = NULL;
return TRUE;
}
//
//The Uninitialize of DRCB.
//
VOID DrcbUninitialize(__COMMON_OBJECT* lpThis)
{
__DRCB* lpDrcb = NULL;
if(NULL == lpThis)
return;
lpDrcb = (__DRCB*)lpThis;
if(lpDrcb->lpSynObject != NULL)
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)(lpDrcb->lpSynObject));
return;
}
//
//The implementation of driver object's initialize routine.
//
BOOL DrvObjInitialize(__COMMON_OBJECT* lpThis)
{
__DRIVER_OBJECT* lpDrvObj = NULL;
if(NULL == lpThis)
return FALSE;
lpDrvObj = (__DRIVER_OBJECT*)lpThis;
lpDrvObj->lpPrev = NULL;
lpDrvObj->lpNext = NULL;
return TRUE;
}
//
//The implementation of driver object's Uninitialize routine.
//
VOID DrvObjUninitialize(__COMMON_OBJECT* lpThis)
{
return;
}
//
//The implementation of device object's initialize routine.
//
BOOL DevObjInitialize(__COMMON_OBJECT* lpThis)
{
__DEVICE_OBJECT* lpDevObject = NULL;
if(NULL == lpThis)
return FALSE;
lpDevObject = (__DEVICE_OBJECT*)lpThis;
lpDevObject->lpPrev = NULL;
lpDevObject->lpNext = NULL;
lpDevObject->DevName[0] = 0;
//lpDevObject->dwDevType = DEVICE_TYPE_NORMAL;
lpDevObject->lpDriverObject = NULL;
lpDevObject->dwStartPort = 0L;
lpDevObject->dwEndPort = 0L;
lpDevObject->dwDmaChannel = 0L;
lpDevObject->dwInterrupt = 0L;
lpDevObject->lpMemoryStartAddr = NULL;
lpDevObject->dwMemLen = NULL;
lpDevObject->lpDevExtension = NULL;
return TRUE;
}
//
//Device object's Uninitialize routine.
//
VOID DevObjUninitialize(__COMMON_OBJECT* lpThis)
{
return;
}
//
//The implementation of IOManager.
//
//
//The initialize routine of IOManager.
//This routine does the following:
// 1.
//
static BOOL IOManagerInitialize(__COMMON_OBJECT* lpThis)
{
BOOL bResult = FALSE;
__IO_MANAGER* lpIoManager = NULL;
if(NULL == lpThis) //Parameter check.
return bResult;
bResult = TRUE;
return bResult;
}
//
//The CreateFile routine's implementation of IOManager.
//Several tips about this routine:
// 1. In current version implementation of Hello China,all devices are treated as files,
// so,if users want to access device,he or she can open the target device by calling
// this routine;
// 2. One file or device can be opend as READ ONLY,WRITE ONLY,or READ WRITE,the dwAccessMode
// parameter of this routine indicates the opening mode;
// 3. In current version,one file or device can be opend more than one time,so,the
// dwShareMode indicates the re-open mode of the currently opend file,for example,if one
// kernel thread opens a file as READ WRITE mode,and also indicates the OS that this
// file can only be re-opend as READ mode(by seting the appropriate value of the
// dwShareMode parameter),so,if there is another kernel thread want to open the file
// as READ WRITE mode or WRITE mode,it will fail,by contraries,if the second kernel
// thread want to open the file only in READ ONLY mode,it will success.
// 4. The last parameter,lpReserved,is a reserved parameter that may be used in the future.
//Once success,this routine returns the base address of the device object that opend,
//otherwise,it will return a NULL value to indicate the failure,user can determine the
//failing reason by calling GetLastError routine.
//
//The routine does the following:
// 1.
//
static __COMMON_OBJECT* CreateFile(__COMMON_OBJECT* lpThis,
LPSTR lpszFileName,
DWORD dwAccessMode,
DWORD dwShareMode,
LPVOID lpReserved)
{
__COMMON_OBJECT* lpFileObj = NULL;
if((NULL == lpThis)
|| (NULL == lpszFileName)) //Parameters check.
return lpFileObj;
return lpFileObj;
}
//
//The ReadFile's implementation.
//The routine does the following:
// 1. Create a DRCB object,and initializes it;
// 2. Get the read block size of this device;
// 3. According to the block size,submit the read quest;
// 4. According to the result,set appropriate return value(s).
//
static BOOL ReadFile(__COMMON_OBJECT* lpThis,
__COMMON_OBJECT* lpFileObj,
DWORD dwByteSize,
LPVOID lpBuffer,
DWORD* lpdwReadSize)
{
BOOL bResult = FALSE;
__DRCB* lpDrcb = NULL;
__IO_MANAGER* lpIoManager = NULL;
__DEVICE_OBJECT* lpDevObject = NULL;
__DRIVER_OBJECT* lpDrvObject = NULL;
DWORD dwReadBlockSize = 0L;
DWORD dwTotalSize = 0L;
if((NULL == lpThis)
|| (NULL == lpFileObj)
|| (0 == dwByteSize)
|| (NULL == lpBuffer)) //Parameters check.
goto __TERMINAL;
lpIoManager = (__IO_MANAGER*)lpThis;
lpDevObject = (__DEVICE_OBJECT*)lpFileObj;
lpDrvObject = lpDevObject->lpDriverObject;
lpDrcb = (__DRCB*)ObjectManager.CreateObject(&ObjectManager,
NULL,
OBJECT_TYPE_DRCB);
if(NULL == lpDrcb) //Failed to create DRCB object.
goto __TERMINAL;
if(!lpDrcb->Initialize((__COMMON_OBJECT*)lpDrcb)) //Failed to initialize.
goto __TERMINAL;
//
//The following code gets the read block size by calling DeviceCtrl.
//
lpDrcb->dwRequestMode = DRCB_REQUEST_MODE_IOCTRL;
lpDrcb->dwCtrlCommand = IOCONTROL_GET_READ_BLOCK_SIZE;
lpDrcb->dwStatus = DRCB_STATUS_INITIALIZED;
lpDrcb->dwOutputLen = sizeof(DWORD);
lpDrcb->lpOutputBuffer = (LPVOID)&dwReadBlockSize; //When returned,the read block
//size will be countained in
//dwReadBlockSize variable.
lpDrcb->WaitForCompletion = WaitForCompletion; //Initializes the control routine.
lpDrcb->OnCompletion = OnCompletion;
lpDrcb->OnCancel = OnCancel;
lpDrvObject->DeviceCtrl((__COMMON_OBJECT*)lpDrvObject,
(__COMMON_OBJECT*)lpDevObject,
lpDrcb);
if(DRCB_STATUS_SUCCESS != lpDrcb->dwStatus) //Can not get read block size successfully.
goto __TERMINAL;
//
//The following code commits the read operations by calling DeviceRead routine.
//
dwTotalSize = dwByteSize;
lpDrcb->dwRequestMode = DRCB_REQUEST_MODE_READ;
lpDrcb->dwStatus = DRCB_STATUS_INITIALIZED;
while(TRUE)
{
lpDrcb->dwOutputLen =
dwTotalSize > dwReadBlockSize ? dwReadBlockSize : dwTotalSize;
lpDrcb->lpOutputBuffer =
lpBuffer;
lpDrvObject->DeviceRead((__COMMON_OBJECT*)lpDrvObject,
(__COMMON_OBJECT*)lpDevObject,
lpDrcb);
if(DRCB_STATUS_SUCCESS != lpDrcb->dwStatus) //Can not read successfully.
goto __TERMINAL; //Exit the read process.
if(lpDrcb->dwOutputLen < dwReadBlockSize) //This suituation indicates the following
//case:
//1. At the end of the target file,but
// the original request data size is
// not satisfied;
//2. The read transaction is over.
//
{
*lpdwReadSize = dwByteSize - dwTotalSize;
*lpdwReadSize += lpDrcb->dwOutputLen; //Set the actually read byte size.
bResult = TRUE;
goto __SUCCESSFUL;
}
dwTotalSize -= dwReadBlockSize;
if(0 == dwTotalSize)
{
*lpdwReadSize = dwByteSize;
bResult = TRUE;
goto __SUCCESSFUL;
}
lpBuffer = (LPVOID)((DWORD)lpBuffer + dwReadBlockSize);
}
__SUCCESSFUL:
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpDrcb); //Destroy the DRCB object.
__TERMINAL:
if(!bResult) //This routine failed.
{
if(lpDrcb != NULL) //Destroy the DRCB object.
{
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpDrcb);
}
}
return bResult;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -