当前位置: 首页 > news >正文

深圳的网站设计网页设计模板流程图

深圳的网站设计,网页设计模板流程图,企业网站建设价格,百度云网站建设视频教程User Mode Driver介绍 Windows CE 6.0中引入了User Mode Driver的概念#xff0c;可是无论是网上#xff0c;还是各个芯片厂商提供的方案中#xff0c;都很少提及这方面的内容。 本文以小郭对存储管理和User Mode Driver Host的理解为基础#xff0c;结合具体的代码实现可是无论是网上还是各个芯片厂商提供的方案中都很少提及这方面的内容。 本文以小郭对存储管理和User Mode Driver Host的理解为基础结合具体的代码实现从User Mode Driver的加载流程的角度分析了存储管理对User Mode Driver的处理过程。 由于个人知识水平和项目经验有限难免有些地方错误还望你不吝指出特此说明。 一      User Mode Driver与Kernel Mode Driver 1User Mode Driver与Kernel Mode Driver 顾名思义User Mode Driver就是运行在User Mode的Driver而Kernel Mode Driver是运行在Kernel Mode的Driver。 User Mode和Kernel Mode的有很多差别首先运行在Kernel Mode的程序一般都是处理系统的核心功能的程序而运行在User Mode多是一些与应用有关的程序或者驱动再者运行在User Mode下的程序不可以进行物理内存映射和调用中断处理相关函数而运行在Kernel Mode下的程序和驱动却没有这方面的限制。 在这里我着重说的是User Mode和Kernel Mode下内存访问权限的差别。 运行在User Mode下的程序合法的虚拟内存空间访问权限如下 ReadVM_USER_BASE0x00010000~ VM_KMODE_BASE0x80000000 WriteVM_USER_BASE0x00010000~ VM_SHARED_HEAP_BASE0x70000000 而运行在Kernel Mode下的程序可以自由地访问4GB的内存空间对32位机而言。 在老版本的Windows CE5.0中所有的Driver和应用程序都运行在User Mode下。操作系统提供了API SetKMode()来在User Mode和Kernel Mode之间自由地切换提供了API SetProcPermissions()来提升线程的访问权限。另外Platform Builder提供了编译选项Full Kernel Mode来决定是否让系统中所有的程序包括驱动和应用程序都运行在Kernel Mode下。 显然如果一支应用程序恶意的去访问修改Kernel Mode下的一些参数或者结构体的话整个系统就会增加很多风险。所以在Windows CE 6.0中Microsoft将桌面操作系统中的内存管理策略引入进来。例如所有的Driver都运行在Kernel Mode下而应用程序运行在User Mode下。 当然Microsoft也不想让一些写的很差的Driver以及一些有缺陷的Driver运行在Kernel Mode下由此提出了和桌面操作系统类似的概念User Mode Driver Framework。通过User Mode Driver Framework编写出来的Driver也就是User Mode Driver将运行在User Mode下。 熟悉Microsoft Windows桌面驱动程序的人都应该知道驱动程序包括三种模型分别是虚拟设备驱动程序Virtual Device Driver内核模式驱动程序Kernel Mode Driver和Win32驱动程序模型Win32 Driver Mode。所以User Mode Driver Framework是一个很老的概念。 2Windows CE 6.0中User Mode Driver Framework简介 User Mode Driver Framework包括两部分第一部分是User Mode Driver ReflectorReflector/Service有的地方也成为Reflector Service它存在于Device Manager中第二部分是User Mode Driver Host它被User Mode Driver Reflector进行加载和管理运行在User Mode下。 User Mode Driver Reflector加载User Mode Driver Host后会将I/O请求传递给它然后User Mode Driver Host将I/O请求传递给User Mode Driver。 由于User Mode的局限性User Mode Driver不允许访问硬件例如不允许使用中断函数以及映射物理内存的函数等。为了解决这个问题User Mode Driver调用User Mode Driver Reflector来处理类似的这些请求。User Mode Driver Reflector会去检查Registry的配置去决定是否响应这些要求。 这部分内容可以用下面的几张图来进行描述 第一张摘自帮助文档其中Parent Bus Driver就是CEDDK Driver而Reflector/Service就是User Mode Driver Reflector。 第二图摘自微软官方关于Windows CE6.0的PPT介绍。 二      User Mode Driver Host的加载 1User Mode Driver Host Manager的初始化 在Device.dll被kernel.dll加载起来的后Device.dll中的函数StartDeviceManager()将会被kernel.dll调用并执行。该函数会去调用InitUserProcMgr()以完成对User Mode Driver Process进行管理的一系列初始化工作。 函数InitUserProcMgr()完成的初始化工作非常简单就是创建并初始化类UDPContainer和 UDServiceContainer实例并赋值给全局变量g_pUDPContainer和g_pServiceContainer然后调用类的初始化函数。 类UDPContainer用来维护所有User Mode Driver Host的进程。在其初始化过程中会创建一个类UDPContainer的对象然后调用InsertObjectBy插入到一个莫名其妙的链表中另外到注册表[HKEY_LOCAL_MACHINE/Drivers]下查找默认的User Group名字和Prefix对于那些没有指定使用哪个User Group也即User Mode Driver Host的Driver将会使用这个User Mode Driver Host进行管理。 类UDPContainer可以用下图来描述 类UDServiceContainer同样是用来维护所有User Mode Driver Host的Reflector Service每一个User Mode Driver都会存在一个类UserDriverService的实例而UDServiceContainer则维护着这些UserDriverService结点。在它的初始化过程中会调用API CreateAPISet()和RegisterAPISet()向系统注册ReflServApiMethods[]。ReflServApiMethods包括了函数REFL_DevCloseFileHandle和REFL_DevDeviceIoControl。 当调用CEDDK BUS Driver中BusIoControl() 以及BusTransBusAddrToVirtual()等函数时实际上执行的就是REFL_DevDeviceIoControl()。 类UDServiceContainer的作用可以用下图来进行描述 相关的部分代码如下 extern C BOOL InitUserProcMgr() {      if ( !g_pUDPContainer ) {          // 这里会去创建一个UDPContainer对象并把地址赋给全局变量g_pUDPContainer          // 这个步骤的意义是会去[HKEY_LOCAL_MACHINE/Drivers]下查找默认的User Group名字和Prefix          // 对于那些没有指定使用哪个User Group也即User Mode Driver Host的Driver将会使用这个User Mode Driver Host进行管理          g_pUDPContainer new UDPContainer();          if (g_pUDPContainer!NULL !g_pUDPContainer-Init()) {               delete g_pUDPContainer;               g_pUDPContainer NULL;          }      }      ASSERT(g_pUDPContainer!NULL);      if (!g_pServiceContainer) {          g_pServiceContainer new UDServiceContainer();          if (g_pServiceContainer!NULL !g_pServiceContainer-Init()) {               delete g_pServiceContainer;               g_pServiceContainer NULL;          }        }      ASSERT(g_pServiceContainer!NULL) ;      return (g_pUDPContainer!NULL g_pServiceContainer!NULL); }   const PFNVOID ReflServApiMethods[] {      (PFNVOID)REFL_DevCloseFileHandle,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)0,      (PFNVOID)REFL_DevDeviceIoControl, };   #define NUM_REFL_SERV_APIS (sizeof(ReflServApiMethods)/sizeof(ReflServApiMethods[0]))   const ULONGLONG ReflServApiSigs[NUM_REFL_SERV_APIS] {      FNSIG1(DW),                 // CloseFileHandle      FNSIG0(),      FNSIG5(DW,I_PTR,DW,O_PDW,IO_PDW),   // ReadFile      FNSIG5(DW,O_PTR,DW,O_PDW,IO_PDW),   // WriteFile      FNSIG2(DW,O_PDW),                   // GetFileSize      FNSIG4(DW,DW,O_PDW,DW),             // SetFilePointer      FNSIG2(DW,O_PDW),                   // GetDeviceInformationByFileHandle      FNSIG1(DW),                         // FlushFileBuffers      FNSIG4(DW,O_PDW,O_PDW,O_PDW),       // GetFileTime      FNSIG4(DW,IO_PDW,IO_PDW,IO_PDW),    // SetFileTime      FNSIG1(DW),                         // SetEndOfFile,      FNSIG8(DW, DW, I_PTR, DW, O_PTR, DW, O_PDW, IO_PDW), // DeviceIoControl }; BOOL UDServiceContainer::Init() {      BOOL bReturn FALSE;      // Before any process can become a handle server, the process must create and register a handle-based API set      // with this function and RegisterAPISet.      m_hDevFileApiHandle CreateAPISet(REFL, NUM_REFL_SERV_APIS, ReflServApiMethods, ReflServApiSigs );      if (m_hDevFileApiHandle!INVALID_HANDLE_VALUE)          bReturn RegisterAPISet(m_hDevFileApiHandle, HT_FILE | REGISTER_APISET_TYPE);      ASSERT(m_hDevFileApiHandle!INVALID_HANDLE_VALUE bReturn) ;      return bReturn; }; // 这里会去创建一个UserDriverProcessor的对象然后调用InsertObjectBy插入到一个莫名其妙的链表中 // 另外会去[HKEY_LOCAL_MACHINE/Drivers]下查找默认的User Group名字和Prefix // 对于那些没有指定使用哪个User Group也即User Mode Driver Host的Driver将会使用这个User Mode Driver Host进行管理 UDPContainer::UDPContainer() {      m_dwCurIndex UDP_RANDOM_PROCESSOR_START_OFFSET ;      m_lpProcName NULL;      DWORD dwLen 0;      DWORD dwType;        CRegistryEdit regKey(HKEY_LOCAL_MACHINE , DEVLOAD_DRIVERS_KEY );        if (regKey.IsKeyOpened() regKey.RegQueryValueEx(UPD_REG_PROCESSOR_NAME_VAL,dwType,NULL,dwLen) dwType UPD_REG_PROCESSOR_NAME_TYPE) {          dwLen min(dwLen / sizeof(TCHAR) 1, MAX_PATH) ;          m_lpProcName new TCHAR [dwLen];          if (m_lpProcName !regKey.GetRegValue(UPD_REG_PROCESSOR_NAME_VAL,(LPBYTE)m_lpProcName,dwLen*sizeof(TCHAR))) {               delete [] m_lpProcName;               m_lpProcName NULL;          }          if (m_lpProcName)               m_lpProcName[dwLen-1] 0;      }      m_lpProcVolName NULL;      if (regKey.IsKeyOpened() regKey.RegQueryValueEx(UDP_REG_PROCESSOR_VOLPREFIX_VAL,dwType,NULL,dwLen) dwType UDP_REG_PROCESSOR_VOLPREFIX_TYPE) {          dwLen min(dwLen / sizeof(TCHAR) 1, MAX_PATH) ;          m_lpProcVolName new TCHAR [dwLen];          if (m_lpProcVolName !regKey.GetRegValue(UDP_REG_PROCESSOR_VOLPREFIX_VAL,(LPBYTE)m_lpProcVolName,dwLen*sizeof(TCHAR))) {               delete [] m_lpProcVolName;               m_lpProcVolName NULL;          }          if (m_lpProcVolName)               m_lpProcVolName[dwLen-1] 0;      }      if (!(regKey.IsKeyOpened() regKey.GetRegValue(UDP_REG_PROCESSOR_TIMEOUT_VAL,(LPBYTE)m_dwProgTimeout,sizeof(DWORD)))) { // If failed we use default.          m_dwProgTimeout UDP_REG_PROCESSOR_TIMEOUT_DEFAULT ;      } } 2. User Mode Driver Host进程的创建过程 1 检查注册表判断是否是User Mode Driver 当设备管理器调用ActivateDeviceEx()来加载流驱动的时候如果发现设备的注册表中指定了该设备驱动是一个User Mode Driver的时候则设备管理器将会通过Reflector Service来加载流驱动。 这部分代码可以参照文件DEVICE/DEVCORE/devload.c中的函数CreateDevice()如下 // 可以看到创建user mode driver的唯一条件就是dwFlags DEVFLAGS_LOAD_AS_USERPROC0         if ((dwFlags DEVFLAGS_LOAD_AS_USERPROC)) {             lpdev-hLib NULL;             lpdev-dwData  Reflector_Create(lpszDeviceKey, pEffType, lpszLib, dwFlags );             if (lpdev-dwData ! 0 ) {                 lpdev-fnInit NULL;                 lpdev-fnInitEx (pInitExFn)Reflector_InitEx;                 lpdev-fnPreDeinit (pDeinitFn)Reflector_PreDeinit;                 lpdev-fnDeinit (pDeinitFn)Reflector_Deinit;                 lpdev-fnOpen (pOpenFn)Reflector_Open;                 lpdev-fnPreClose (pCloseFn)Reflector_PreClose;                 lpdev-fnClose (pCloseFn)Reflector_Close;                 lpdev-fnRead (pReadFn)Reflector_Read;                 lpdev-fnWrite (pWriteFn)Reflector_Write;                 lpdev-fnSeek (pSeekFn)Reflector_SeekFn;                 lpdev-fnControl (pControlFn)Reflector_Control;                 lpdev-fnPowerup (pPowerupFn)Reflector_Powerup;                 lpdev-fnPowerdn (pPowerupFn)Reflector_Powerdn;             }             else {                 DEBUGMSG(ZONE_WARNING, (_T(DEVICE!CreateDevice: couldnt load(%s) to user mode!!/r/n),lpszLib));                 dwStatus ERROR_FILE_NOT_FOUND;             }         }         else {             DEBUGMSG(ZONE_ACTIVE, (_T(DEVICE!CreateDevice: loading driver DLL %s/r/n), lpszLib));             // 下面这里会去判断两种load  library的方式             lpdev-hLib                 (dwFlags DEVFLAGS_LOADLIBRARY) ? LoadLibrary(lpszLib) : LoadDriver(lpszLib);             if (!lpdev-hLib) {                 DEBUGMSG(ZONE_WARNING, (_T(DEVICE!CreateDevice: couldnt load %s -- error %d/r/n),                     lpszLib, GetLastError()));                 dwStatus ERROR_FILE_NOT_FOUND;             } else {                 lpdev-fnInitEx NULL;                 lpdev-fnInit (pInitFn)GetDMProcAddr(pEffType,LInit,lpdev-hLib);                 lpdev-fnPreDeinit (pDeinitFn)GetDMProcAddr(pEffType,LPreDeinit,lpdev-hLib);                 lpdev-fnDeinit (pDeinitFn)GetDMProcAddr(pEffType,LDeinit,lpdev-hLib);                 lpdev-fnOpen (pOpenFn)GetDMProcAddr(pEffType,LOpen,lpdev-hLib);                 lpdev-fnPreClose (pCloseFn)GetDMProcAddr(pEffType,LPreClose,lpdev-hLib);                 lpdev-fnClose (pCloseFn)GetDMProcAddr(pEffType,LClose,lpdev-hLib);                 lpdev-fnRead (pReadFn)GetDMProcAddr(pEffType,LRead,lpdev-hLib);                 lpdev-fnWrite (pWriteFn)GetDMProcAddr(pEffType,LWrite,lpdev-hLib);                 lpdev-fnSeek (pSeekFn)GetDMProcAddr(pEffType,LSeek,lpdev-hLib);                 lpdev-fnControl (pControlFn)GetDMProcAddr(pEffType,LIOControl,lpdev-hLib);                 lpdev-fnPowerup (pPowerupFn)GetDMProcAddr(pEffType,LPowerUp,lpdev-hLib);                 lpdev-fnPowerdn (pPowerdnFn)GetDMProcAddr(pEffType,LPowerDown,lpdev-hLib);                   // Make sure that the driver has an init and deinit routine.  If it is named,                 // it must have open and close, plus at least one of the I/O routines (read, write                 // ioctl, and/or seek).  If a named driver has a pre-close routine, it must also                 // have a pre-deinit routine.                 if (!(lpdev-fnInit lpdev-fnDeinit) ||                     lpdev-pszDeviceName ! NULL (!lpdev-fnOpen ||                                  !lpdev-fnClose ||                                  (!lpdev-fnRead !lpdev-fnWrite                                   !lpdev-fnSeek !lpdev-fnControl) ||                                  (lpdev-fnPreClose !lpdev-fnPreDeinit))) {                     DEBUGMSG(ZONE_WARNING, (_T(DEVICE!CreateDevice: illegal entry point combination in driver DLL %s/r/n),                         lpszLib));                     dwStatus ERROR_INVALID_FUNCTION;                 }                   if (!lpdev-fnOpen) lpdev-fnOpen (pOpenFn) DevFileNotSupportedBool;                 if (!lpdev-fnClose) lpdev-fnClose (pCloseFn) DevFileNotSupportedBool;                 if (!lpdev-fnControl) lpdev-fnControl (pControlFn) DevFileNotSupportedBool;                 if (!lpdev-fnRead) lpdev-fnRead (pReadFn) DevFileNotSupportedDword;                 if (!lpdev-fnWrite) lpdev-fnWrite (pWriteFn) DevFileNotSupportedDword;                 if (!lpdev-fnSeek) lpdev-fnSeek (pSeekFn) DevFileNotSupportedDword;             }         } 2 User Mode Drive Host进程的创建过程 从上面粘贴出来的代码中可以看到设备管理器中会去调用Reflector_Create()该函数就属于Reflector Service其实User Mode Driver Host进程就是在这里被创建的。 函数Reflector_Create()实质上直接去调用CReflector * CreateReflector()。 函数CReflector * CreateReflector()会去读取User Mode Driver注册表下UserProcGroup的键值然后调用FindUserProcByID()去到类UDPContainer的成员m_rgLinkList指向的链表中去查询系统中有没有该User Mode Driver Host如果没有的话则调用UDPContainer::CreateUserProcByGroupID()去读取其ProcName和ProcVolPrefix去创建该User Mode Driver Host进程。 有关这部分代码如下 // 看清楚了这个不是类的method而是一个返回类实例指针的函数 // 另外该函数的功能就是根据lpszDeviceKey的值到当前系统中去寻找是否有对应的user mode driver host // 进程已经创建起来如果有则返回其指针 // 如果没有的话则查询注册表中相应的配置值并创建起进程 CReflector * CreateReflector(LPCTSTR lpszDeviceKey, LPCTSTR lpPreFix, LPCTSTR lpDrvName, DWORD dwFlags ) {      CRegistryEdit m_DeviceKey (HKEY_LOCAL_MACHINE, lpszDeviceKey);      DWORD dwUserProcGroupID 0;      CReflector * pReturn NULL;      UserDriverProcessor * pUserDriverProc NULL;      DWORD dwRetry 2;      do {          //获取注册表中TEXT(UserProcGroup)的值其实也就是获取user mode driver host的编号          if (m_DeviceKey.IsKeyOpened() m_DeviceKey.GetRegValue(DEVLOAD_USERPROCGROUP_VALNAME,(PBYTE)dwUserProcGroupID, sizeof(dwUserProcGroupID))) {               pUserDriverProc FindUserProcByID(dwUserProcGroupID,TRUE);          }          // 判断传入的参数lpszDeviceKey是不是Lservices//          else if (IsServicesRegKey(lpszDeviceKey)) {               // Not all services may have explicitly set their group explicitly               // in registry, so steer them to default here.               // 可以看到service.exe固定为group2               pUserDriverProc FindUserProcByID(SERVICEDS_EXE_DEFAULT_PROCESSOR_ID,TRUE);          }          else {               pUserDriverProc CreateUserProc ();               if (pUserDriverProc)                    pUserDriverProc-AddRef();          };          if (pUserDriverProc) {               pReturn pUserDriverProc-CreateReflector(lpPreFix, lpDrvName,dwFlags);               pUserDriverProc-DeRef();          }          if (pReturnNULL)               Sleep(1000);      } while (dwRetry-- ! 0 pReturn NULL);      DEBUGMSG(ZONE_WARNING pReturnNULL,(LCreateReflector : failed to create refelctor object));      return pReturn; } // 按照group id来查找系统当前的user mode driver host如果没有找到的话就到系统的注册表 // 中查找其对应的注册表信息然后创建其进程 // 例如查找dwUserProcGroupID3系统中没有找到的话会查询注册表并创建进程udevice.exe // param: //        dwUserProcGroupID: user group id //        fCreateOnNoExit: 如果当前系统中不存在个该group的话是否创建该group的线程 inline UserDriverProcessor * FindUserProcByID(DWORD dwUserProcGroupID,BOOL fCreateOnNoExit) {     if (g_pUDPContainer)         return g_pUDPContainer-FindUserProcByID(dwUserProcGroupID,fCreateOnNoExit);     else         return NULL; } // 这里用user process group id到链表m_rgLinkList中查找UserDriverProcessor // param: //        dwUserProcGroupID: user group id //        fCreateOnNoExit: 如果当前系统中不存在个该group的话是否创建该group的线程 UserDriverProcessor * UDPContainer::FindUserProcByID(DWORD dwUserProcGroupID,BOOL fCreateOnNoExit) {      UserDriverProcessor * pReturn NULL;      if (dwUserProcGroupID UDP_RANDOM_PROCESSOR_START_OFFSET dwUserProcGroupID ! 0) {          Lock();          UserDriverProcessor *  pCur m_rgLinkList;          while (pCur) {               if (pCur-GetProcID() dwUserProcGroupID ) {                    pReturn pCur;                    break;               }               else {                    pCur pCur-GetNextObject();               }          }          if (pReturn) {               pReturn-AddRef();          }          // 如果当前系统中不存在该user group则创建该group的          if (pReturn NULL fCreateOnNoExit) {               UserDriverProcessor * pNewProc CreateUserProcByGroupID(dwUserProcGroupID);               if (pNewProc) { // This is newly created. So it should succeeded.                    pReturn FindUserProcBy(pNewProc);                    ASSERT(pReturn);               }          }          Unlock();      }      else {          UserDriverProcessor * pNewProc CreateUserProc () ;          if (pNewProc) {               pReturn FindUserProcBy(pNewProc);               ASSERT(pReturn);          }      }      ASSERT(pReturn);      return pReturn; } // 这里会去创建一个UserDriverProcessor的对象然后调用InsertObjectBy插入到一个莫名其妙的链表中 // UserDriverProcessor * UDPContainer::CreateUserProcByGroupID(DWORD dwUserProcGroupID) {      TCHAR lpGroupSubKeyPath[MAX_PATH] ;      LPCTSTR lpProcName m_lpProcName;      LPCTSTR lpProcVolName m_lpProcVolName;      TCHAR localProcName[MAX_PATH];      TCHAR localProcVolume[MAX_PATH];      DWORD dwProgTimeout m_dwProgTimeout ;        // 读取group_***的注册表值      CRegistryEdit regKey(HKEY_LOCAL_MACHINE , DEVLOAD_DRIVERS_KEY );      if (regKey.IsKeyOpened() SUCCEEDED(StringCchPrintf(lpGroupSubKeyPath,MAX_PATH,TEXT(%s_%04x),UDP_REGKEY_PROCESSOR_GROUP_PREFIX,dwUserProcGroupID))) {          CRegistryEdit groupSubKey(regKey.GetHKey(),lpGroupSubKeyPath);          if (groupSubKey.IsKeyOpened()) {               DWORD dwType;               DWORD dwLen sizeof(localProcName);               if (groupSubKey.RegQueryValueEx(UPD_REG_PROCESSOR_NAME_VAL,dwType,(LPBYTE)localProcName,dwLen) dwType UPD_REG_PROCESSOR_NAME_TYPE) {                    localProcName[MAX_PATH-1] 0 ; // Force to terminate if it is not.                    lpProcName localProcName;               }               dwLen sizeof(localProcVolume) ;               if (groupSubKey.RegQueryValueEx(UDP_REG_PROCESSOR_VOLPREFIX_VAL,dwType,(LPBYTE)localProcVolume,dwLen) dwType UDP_REG_PROCESSOR_VOLPREFIX_TYPE) {                    localProcVolume[MAX_PATH-1] 0 ; // Force to terminate if it is not.                    lpProcVolName localProcVolume;               }               DWORD dwTimeout;               if (groupSubKey.GetRegValue(UDP_REG_PROCESSOR_TIMEOUT_VAL,(LPBYTE)dwTimeout,sizeof(DWORD))) {                    dwProgTimeout dwTimeout ;               }          }      }      Lock();        // 创建user proc的时候需要prefix/process name/timeout值      UserDriverProcessor * pNewProc new UserDriverProcessor(dwUserProcGroupID,lpProcName,lpProcVolName,dwProgTimeout);      if (pNewProc!NULL !pNewProc-Init()) { // Init Fails.          delete pNewProc;          pNewProc NULL;      }      if (pNewProc) {          if (InsertObjectBy(pNewProc)NULL) { // Something Really Bad.               ASSERT(FALSE);               delete pNewProc;               pNewProc NULL;          }      }      Unlock();      return pNewProc; }; // 创建user mode driver host进程 BOOL UserDriverProcessor::Init() {      BOOL bReturn FALSE;      Lock();      if (m_lpProcName!NULL m_lpProcVolName!NULL) {          // We have to lauch processor with the value name          // 第二个参数就是m_lpProcVolName也就是注册表项ProcVolPrefix的值作为参数传递给m_lpProcName          bReturn CreateProcess( m_lpProcName, m_lpProcVolName, NULL, NULL, FALSE, 0, NULL, NULL, NULL,m_ProcessInformation);          if (bReturn)  {               DWORD dwWaitTicks m_dwTimewout ;               while (!SendIoControl(IOCTL_USERPROCESSOR_ALIVE,NULL,0,NULL,0,NULL) dwWaitTicks!0) {                    if (WaitForSingleObject(m_ProcessInformation.hProcess,TIMOUT_INTERVAL) WAIT_OBJECT_0)                        break;                    if (dwWaitTicksTIMOUT_INTERVAL )                        break;                    else                        dwWaitTicks- TIMOUT_INTERVAL;               }               bReturn (WaitForSingleObject(m_ProcessInformation.hProcess,1)! WAIT_OBJECT_0);               DEBUGMSG(ZONE_WARNING !dwWaitTicks,(TEXT(REFLECTOR! Processor %s %s is not responding!/r/n),m_lpProcName,m_lpProcVolName));               DEBUGMSG(ZONE_ERROR !bReturn,(TEXT(REFLECTOR! Processor %s %s is dead!!!/r/n),m_lpProcName,m_lpProcVolName));          }      }      Unlock();      ASSERT(bReturn);      return bReturn; } 至此User Mode Driver Host进程就已经创建起来了。 3User Mode Driver Host和Reflector Service之间的通信 在上述的过程中值的注意的一点是创建User Mode Driver Host进程的时候传入参数m_lpProcVolName 将会用来向系统注册User Mode Driver Host的API时候使用。它形如$udevice_XXX [***为group ID]。 例如udevice.exe的入口函数WinMain中会去调用RegisterAFSAPI来向系统注册FS API其中就用到了上面传入的m_lpProcVolName这部分代码如下 // This routine is the entry point for the device manager.  It simply calls the device // management DLLs entry point. // 这里就是udevice.exe的入口 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmdShow) {     int status-1;     DEBUGMSG(1,(TEXT(udevice.exe %s /r/n),lpCmdLine));        DEBUGREGISTER(NULL);       if (RegisterAFSAPI(lpCmdLine)) {         BOOL bRet (WaitForPrimaryThreadExit(INFINITE)   WAIT_OBJECT_0) ;         ASSERT(bRet);     }     else         ASSERT(FALSE);     DEBUGMSG(1,(TEXT(exiting udevice.exe/r/n)));        UnRegisterAFSAPI();     return status; } // 调用CreateAPISet和RegisterAPISet创建udevice.exe的api以方便后续的操作 // 这里传入的参数就是创建udevice.exe和servicesd.exe进程的时候传入的参数 // cflector中创建user mode driver host进程时候传入的参数 BOOL RegisterAFSAPI (LPCTSTR VolString) {     g_pUserDriverContainer new UserDriverContainer () ;         ghDevFileApiHandle CreateAPISet(W32D, NUM_UD_SERV_APIS, UdServApiMethods, UdServApiSigs );     BOOL bReturn FALSE;     if (ghDevFileApiHandle!INVALID_HANDLE_VALUE)         bReturn RegisterAPISet(ghDevFileApiHandle, HT_FILE | REGISTER_APISET_TYPE);     ASSERT(ghDevFileApiHandle!INVALID_HANDLE_VALUE bReturn) ;         //Before any process can become a handle server, the process must create and register a handle-based API set with CreateAPISet and RegisterAPISet.     ghDevFSAPI CreateAPISet(UDFA, ARRAYSIZE(gpfnDevFSAPIs), (const PFNVOID *) gpfnDevFSAPIs, gDevFSSigs);     RegisterAPISet (ghDevFSAPI, HT_AFSVOLUME | REGISTER_APISET_TYPE);     ASSERT(ghDevFSAPI!NULL);     giFSIndex RegisterAFSName(VolString);     ASSERT(giFSIndex!(DWORD)-1);     if (ghDevFSAPI!NULL giFSIndex!(DWORD)-1) {         gfRegisterOK RegisterAFSEx(giFSIndex, ghDevFSAPI, 0 , AFS_VERSION, AFS_FLAG_HIDDEN|AFS_FLAG_KMODE);         ASSERT(gfRegisterOK);     }     if (gfRegisterOK)         ghExit   CreateEvent(NULL,TRUE,FALSE,NULL) ;     ASSERT(ghExit!NULL);         return (g_pUserDriverContainer gfRegisterOK ghExit ghDevFileApiHandle!INVALID_HANDLE_VALUE bReturn); } 这里创建的API如下 // 下面定义的api是用作udevice.exe的管理 extern C BOOL UD_DevDeviceIoControl(DWORD dwContent, DWORD dwIoControlCode, PVOID pInBuf, DWORD nInBufSize, PVOID pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned, OVERLAPPED *pOverlapped); const PFNVOID UdServApiMethods[] {     (PFNVOID)UD_DevCloseFileHandle,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)0,     (PFNVOID)UD_DevDeviceIoControl, };   #define NUM_UD_SERV_APIS (sizeof(UdServApiMethods)/sizeof(UdServApiMethods[0]))   const ULONGLONG UdServApiSigs[NUM_UD_SERV_APIS] {     FNSIG1(DW),                 // CloseFileHandle     FNSIG0(),     FNSIG5(DW,I_PTR,DW,O_PDW,IO_PDW),   // ReadFile     FNSIG5(DW,O_PTR,DW,O_PDW,IO_PDW),   // WriteFile     FNSIG2(DW,O_PDW),                   // GetFileSize     FNSIG4(DW,DW,O_PDW,DW),             // SetFilePointer     FNSIG2(DW,O_PDW),                   // GetDeviceInformationByFileHandle     FNSIG1(DW),                         // FlushFileBuffers     FNSIG4(DW,O_PDW,O_PDW,O_PDW),       // GetFileTime     FNSIG4(DW,IO_PDW,IO_PDW,IO_PDW),    // SetFileTime     FNSIG1(DW),                         // SetEndOfFile,     FNSIG8(DW, DW, IO_PTR, DW, IO_PTR, DW, O_PDW, IO_PDW), // DeviceIoControl }; // 下面定义的api用于FSD的管理 // 因为device.dll和udevice.exe的功能类似所以两个组件都向系统注册了一组自己的api // User Device Manager filesystem APIs static CONST PFNVOID gpfnDevFSAPIs[] {         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)NULL,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_IoControl,         (PFNVOID)DEVFS_StubFunction,         (PFNVOID)DEVFS_StubFunction, }; static CONST ULONGLONG gDevFSSigs[] {         FNSIG0(),                                       // CloseVolume         FNSIG0(),                                       //         FNSIG0(),                                       // CreateDirectoryW         FNSIG0(),                                       // RemoveDirectoryW         FNSIG0(),                                       // GetFileAttributesW         FNSIG0(),                                       // SetFileAttributesW         FNSIG0(),                                       // CreateFileW         FNSIG0(),                                       // DeleteFileW         FNSIG0(),                                       // MoveFileW         FNSIG0(),                                       // FindFirstFileW         FNSIG0(),                                       // CeRegisterFileSystemNotification         FNSIG0(),                                       // CeOidGetInfo         FNSIG0(),                                       // PrestoChangoFileName         FNSIG0(),                                       // CloseAllFiles         FNSIG0(),                                       // GetDiskFreeSpace         FNSIG0(),                                       // Notify         FNSIG0(),                                       // CeRegisterFileSystemFunction         FNSIG0(),                                       // FindFirstChangeNotification         FNSIG0(),                                       // FindNextChangeNotification         FNSIG0(),                                       // FindCloseNotification         FNSIG0(),                                       // CeGetFileNotificationInfo         FNSIG9(DW, DW, DW, IO_PTR, DW, IO_PTR, DW, O_PDW, IO_PDW), // FsIoControlW         FNSIG0(),                                       // SetFileSecurityW         FNSIG0(),                                       // GetFileSecurityW }; 注意上面注册的API的调用方法。其实Reflector Service中就是通过DeviceIoControl()调用上面注册的API的从而和User Mode Driver Host进行通信。 三User Mode Driver的加载 1User Mode Driver被Load到内存的过程 1 流程概述 上面二.1中已经粘贴出来设备管理器在创建User Mode Driver设备时会去调用Reflector Service的函数Reflector_Create()进而调用到函数CReflector * CreateReflector()。 函数CReflector * CreateReflector()完成了两个功能 第一查询OS中是否已经存在所需要的User Mode Driver Host如果没有则创建一个。 查询类UDPContainer维护的UserDriverProcessor实例链表中是否存在所需要的UserDriverProcessor也即User Mode Driver Host。 其实上面也曾提到系统中会在设备管理器初始化的时候创建一个类UDPContainer的实例并通过g_pUDPContainer指向。 如果没有找到对应的User Mode Driver Host则创建一个对应的进程。 另外需要指出的是一个特定的User Mode Driver Host对应一个UserDriverProcessor实例而每一个UserDriverProcessor实例下面维护了一张链表m_ReflectorList可以挂很多个设备驱动。 已经在前面详细的进行过描述这一章节不再进行描述。 第二 为设备创建CReflector实例并将其加入到对应的User Mode Driver Host维护的链表m_ReflectorList中。 上面已经提到User Mode Driver Host和UserDriverProcessor是一一对应的UserDriverProcessor下面维护了使用该User Mode Driver Host的所有User Mode Driver。 在这里一个具体的User Mode Driver的存在形式就是类CReflector实例。 接下来我会着重的描述这部分得代码实现。 有关函数CReflector * CreateReflector()的实现我画了一个流程图如下: 前面已经提到User Mode Driver存在的具体形式就是挂在类UserDriverProcessor上的一个CReflector实例。上述流程图中红颜色方框中的部分就是创建CReflector的实现。接下来我会详细的去分析这部分代码。 2 函数UserDriverProcessor::CreateReflector()在调用User Mode Driver Host之前的Stack 函数UserDriverProcessor::CreateReflector()到CeFsIoControl()过程 从函数UserDriverProcessor::CreateReflector()的实现可以看到其为当前的User Mode Driver创建一个CReflector类实例每一个User Mode Driver都对应一个类 CReflector的实例。     CReflector * UserDriverProcessor::CreateReflector( LPCTSTR lpPreFix, LPCTSTR lpDrvName, DWORD dwFlags) {     CReflector * pRetReflect NULL;     Lock();     if (!m_fTerminate) {         // 这里看清楚非常重要         // 将this传递给创建的CReflector对象然后把CReflector对象加入到类UserDriverProcessor维护的链表中这样UserDriverProcessor和CReflector就可以互相的调用         // 实际上每一个user mode driver host对应一个UserDriverProcessor实例而每一个user mode driver对应一个CReflector实例         pRetReflect new CReflector(this,lpPreFix, lpDrvName, dwFlags);            // 接下来调用的CReflector::Init()就没有做任何事情         if (pRetReflect !pRetReflect-Init()) {             delete pRetReflect;             pRetReflect NULL;         }         if (pRetReflect) {             m_ReflectorList.InsertObjectBy(pRetReflect) ;         }         CheckReflectorForEmpty();     }     Unlock();     return pRetReflect;     } 下面对类CReflector的构造函数进行分析这里是Driver Load到内存的精髓中间牵扯到很多的类和变量。 类CReflector的构造函数会将类UserDriverProcessor对象指针填充到其自己的成员变量m_pUDP后面会用它来调用类UserDriverProcessor的Method。然后调用CReflector::FnDriverLoad()去创建了类对象UserDriver并获取User Mode Driver Host进程向系统注册API的 Handle。前者记录在类CReflector的成员m_dwData中而后者记录到m_hUDriver后续会将其保存到注册项”ReflectorHandle”下,供CEDDK的Bus Driver使用。 // 类CReflector的构造函数 // 参数 //       pUDP其User Mode Driver Host的对象指针 CReflector::CReflector(UserDriverProcessor * pUDP, LPCTSTR lpPreFix, LPCTSTR lpDrvName,DWORD dwFlags, CReflector * pNext) :   m_pUDP(pUDP) ,   m_pNextReflector(pNext) {      m_pFileFolderList NULL;      m_pPhysicalMemoryWindowList NULL;      m_dwData 0 ;      m_fUserInit FALSE ;      m_hInterruptHandle NULL;      m_hIsrHandle NULL;      m_hUDriver INVALID_HANDLE_VALUE ;      m_DdkIsrInfo.cbSize sizeof(m_DdkIsrInfo);      m_DdkIsrInfo.dwSysintr 0;      m_DdkIsrInfo.dwIrq 0;        if (m_pUDP) {          m_pUDP-AddRef();          FNDRIVERLOAD_PARAM fnDriverLoad;          fnDriverLoad.dwAccessKey (DWORD)this;          fnDriverLoad.dwFlags dwFlags;          BOOL fCpyOk FALSE;          __try {               if (lpPreFixNULL) { // Special case. for naked entry.                    fnDriverLoad.Prefix[0] 0 ;                    fCpyOk TRUE;               }               else                    fCpyOk SUCCEEDED(StringCbCopy(fnDriverLoad.Prefix,sizeof(fnDriverLoad.Prefix),lpPreFix));                 fCpyOk (fCpyOk SUCCEEDED(StringCbCopy(fnDriverLoad.DriverName,sizeof(fnDriverLoad.DriverName),lpDrvName)));          }          __except(EXCEPTION_EXECUTE_HANDLER) {               fCpyOk FALSE ;          }            if (fCpyOk) {               FNDRIVERLOAD_RETURN driversReturn;               driversReturn.dwDriverContext 0 ;               driversReturn.hDriversAccessHandle INVALID_HANDLE_VALUE ;                 // m_hUDriver此时仍为INVALID_HANDLE_VALUE后面会对其进行初始化               // 函数FnDriverLoad()调用了之前user mode driver host进程向系统注册的api--DEVFS_IoControl(IOCTL_USERDRIVER_LOAD)               // 完成了两个功能    1.创建了类对象UserDriver并将其填充到driversReturn.dwDriverContext               //                     2.将user mode driver host进程向系统注册的api的handle填充到driversReturn.hDriversAccessHandle               //                          后面会将该Handle记录到注册表中然后CEDDK的Bus Driver会去获取该值并调用相应的功能               BOOL bRet FnDriverLoad(fnDriverLoad,driversReturn);               if (bRet) {                    m_dwData driversReturn.dwDriverContext;                    // 找到了找到了!!!!!!!                    // 这里会为类CReflector的成员m_hUDriver赋值它的值就是driversReturn.hDriversAccessHandle,                    // 也就是指向了udevice.exe或者其他user mode driver host向系统注册api的handle                    if (driversReturn.hDriversAccessHandle!NULL driversReturn.hDriversAccessHandle! INVALID_HANDLE_VALUE m_hUDriverINVALID_HANDLE_VALUE) {                        bRet DuplicateHandle((HANDLE)m_pUDP-GetUserDriverPorcessorInfo().dwProcessId,driversReturn.hDriversAccessHandle,                             GetCurrentProcess(),m_hUDriver,                             0,FALSE,DUPLICATE_SAME_ACCESS);                        if (!bRet || m_hUDriver 0 || m_hUDriver INVALID_HANDLE_VALUE) {                             ASSERT(FALSE);                             m_hUDriver INVALID_HANDLE_VALUE;                        }                    }               }               DEBUGMSG(ZONE_WARNING !bRet,(LCReflector: FnDriverLoad return FALSE!));          }      } } 有关上面提到的函数CReflector::FnDriverLoad()实际上调用了udevice.dll或其它的User Mode Driver Host向系统注册的API DEVFS_IoControl()。 调用的Stack如下 CReflector::FnDriverLoad()àCReflector::SendIoControl()àUserDriverProcessor::SendIoControl()àCeFsIoControl()。 相关代码如下 // 具体完成的工作就是创建UserDriver对象并将其使用类UserDriverContainer进行维护 // 然后将其地址赋值给((PFNDRIVERLOAD_RETURN)driversReturn)-dwDriverContext 并返回同时返回的还有udevice.exe向系统注册api handle BOOL class CReflector::FnDriverLoad(FNDRIVERLOAD_PARAM DriverLoadParam, FNDRIVERLOAD_RETURN driversReturn) {         return SendIoControl(IOCTL_USERDRIVER_LOAD,DriverLoadParam, sizeof(DriverLoadParam),driversReturn, sizeof(FNDRIVERLOAD_RETURN) ,NULL); } // io control of creflector // 该函数究竟调用到哪里和m_hUDriver密切相关 // 在m_hUDriver初始化之前调用到DEVFS_IoControl // 初始化之后调用到UD_DevDeviceIoControl // m_hUDriver的初始化在类CReflector的构造函数的后半部分中完成 BOOL CReflector::SendIoControl(DWORD dwIoControlCode,LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned) {         PREFAST_ASSERT(m_pUDP);      DWORD dwOldCaller UTlsPtr()[ PRETLS_DRIVER_DIRECT_CALLER ] ;      UTlsPtr()[ PRETLS_DRIVER_DIRECT_CALLER ] GetCallerProcessId();      BOOL fReturn FALSE;      // m_hUDriver的初始化是在类CReflector的后半段完成的所以前半段的时候还是会调用到m_pUDP-SendIoControl的      if (m_hUDriver ! INVALID_HANDLE_VALUE)          // 没错这里就调用到了UD_DevDeviceIoControl呵呵因为m_hUDriver就是这些api的handle          // 有关这一部分内容可以参照m_hUDriver的定义和初始化[CReflector的构造函数中定义]          // 其实这里就是CReflector和user mode driver host进行交互的地方          fReturn DeviceIoControl(m_hUDriver, dwIoControlCode,lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned,NULL);      else          // 实际上这里调用的就是DEVFS_IoControl因为DEVFS_IoControl所在文件中已经将          fReturn m_pUDP-SendIoControl(dwIoControlCode,lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned);      UTlsPtr()[ PRETLS_DRIVER_DIRECT_CALLER ] dwOldCaller;         return fReturn ; }; BOOL class UserDriverProcessor::SendIoControl(DWORD dwIoControlCode,LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned) {     //This function sends an I/O control to a file system driver (FSD). It may not be supported by all file system drivers, and not all implementations support all I/O controls     // uses CeFsIoControl to forward the device managers request to the User Mode Driver Host. The User Mode Driver Host then parses the request to either load, unload, or call the parent bus drivers entry.     // 简单说的说CeFsIoControl实际上调用的就是MyFSD_FsIoControl只不过直接调用CeFsIoControl的相当于封装了一下     return CeFsIoControl(m_lpProcVolName,             dwIoControlCode,lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned,NULL); } 最终被调用的函数CeFsIoControl()在实质上调用udevice.exe向系统注册的API DEVFS_IoControl()或其它的User Mode Driver Host向系统注册的其它的API。 未完待续请看下一篇
http://www.yutouwan.com/news/148983/

相关文章:

  • 萍乡网站开发网站推广计划至少应包括
  • 个人网站租用服务器手机网站开发者模式
  • 门户网站开发需求分析网络销售推广
  • 深圳企业网站建设推荐公司建英语网站好
  • 卡片式网站做网站能赚钱么
  • 在上海卖商铺做哪个网站好只有后端可以做网站吗
  • 网站搭建系统百度seo排名优化助手
  • 金融网站模版怎么在百度上推广产品
  • 云栖建站威海网站优化公司
  • 淮北做网站的公司有哪些界面设计图片素材
  • 河北省建设银行网站首页学网络推广哪个培训机构好
  • 代理下单网站开发电商网站服务器空间
  • 门户网站开发设计方案wordpress中文论坛插件
  • 网站开通流程单页面网站教程
  • 做个网站多钱企业免费网站制作
  • 如何选择企业网站开发石家庄市建设局官网
  • 合肥商城网站建设教育 企业 重庆网站建设
  • 高校英文网站建设手机能建设网站
  • 站长工具5g电脑怎么做网站赚钱
  • 生物医药基地网站建设什邡建设局网站
  • 咸阳网站建设公司电话链接买卖平台
  • 延安网站制作都有哪些网站可以做推广
  • 怎样建一个免费网站玉林市网站开发公司电话
  • 重庆专业网站排名团队做资源分享网站怎么样
  • 福州制作手机网站网络推广网站建设方案
  • 企业建站系统下载wordpress大图插件
  • 手机 网站企业网站建设策划书标准版
  • 用idea做html网站施工企业工作环境
  • 网站建设全攻略免费发做网站
  • 网站开发工具链接服务器单位网站建设有机房吗