阅读:1767回复:8
关于动态加载驱动的问题?
各位高手:
不知道哪位使用过Service API动态加载过核心驱动?我曾经读过sinister写的一篇关于这方面的文章,虽然我在本机测试成功,但是我到别的机器上总是不能成功。后来,我用DriverMonitor可以加载,别人说,DriverMornitor也是使用Service API加载驱动的,所以我想问问,对于驱动有没有特殊要求?有没有这方面的开发经验?这里是sinister的写的文章: http://www.whitecell.org/list.php?id=22 |
|
最新喜欢:![]() |
沙发#
发布于:2002-06-21 09:30
再次启动前用Object Viewer一看,设备对象还在,我跟踪了一下,重启服务时代码在StartServie处出来了,看来我要先看看服务状态...呵呵 是的,你也可以查看StartService的错误码,是不是ERROR_SERVICE_ALREADY_RUNNING,然后做进一步的处理。 这是,InstDriver的例子,好像是《UndocumentNT》中的。 ///////////////////////////////////////////////// #include \"stdafx.h\" #include \"winsvc.h\" BOOL InstallDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe ); BOOL StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ); BOOL OpenDevice( IN LPCTSTR DriverName, HANDLE * lphDevice ); BOOL StopDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ); BOOL RemoveDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ); /**************************************************************************** * * FUNCTION: LoadDeviceDriver( const TCHAR, const TCHAR, HANDLE *) * * PURPOSE: Registers a driver with the system configuration manager * and then loads it. * ****************************************************************************/ BOOL LoadDeviceDriver( const TCHAR * Name, const TCHAR * Path, HANDLE * lphDevice ) { SC_HANDLE schSCManager; BOOL okay; schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); // Ignore success of installation: it may already be installed. InstallDriver( schSCManager, Name, Path ); // Ignore success of start: it may already be started. StartDriver( schSCManager, Name ); // Do make sure we can open it. okay = OpenDevice( Name, lphDevice ); CloseServiceHandle( schSCManager ); return okay; } /**************************************************************************** * * FUNCTION: InstallDriver( IN SC_HANDLE, IN LPCTSTR, IN LPCTSTR) * * PURPOSE: Creates a driver service. * ****************************************************************************/ BOOL InstallDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe ) { SC_HANDLE schService; // // NOTE: This creates an entry for a standalone driver. If this // is modified for use with a driver that requires a Tag, // Group, and/or Dependencies, it may be necessary to // query the registry for existing driver information // (in order to determine a unique Tag, etc.). // schService = CreateService( SchSCManager, // SCManager database DriverName, // name of service DriverName, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_KERNEL_DRIVER, // service type SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type ServiceExe, // service\'s binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL // no password ); if ( schService == NULL ) return FALSE; CloseServiceHandle( schService ); return TRUE; } /**************************************************************************** * * FUNCTION: StartDriver( IN SC_HANDLE, IN LPCTSTR) * * PURPOSE: Starts the driver service. * ****************************************************************************/ BOOL StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) { SC_HANDLE schService; BOOL ret; schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS ); if ( schService == NULL ) return FALSE; ret = StartService( schService, 0, NULL ) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING; CloseServiceHandle( schService ); return ret; } /**************************************************************************** * * FUNCTION: OpenDevice( IN LPCTSTR, HANDLE *) * * PURPOSE: Opens the device and returns a handle if desired. * ****************************************************************************/ BOOL OpenDevice( IN LPCTSTR DriverName, HANDLE * lphDevice ) { TCHAR completeDeviceName[64]; HANDLE hDevice; // // Create a \\\\.\\XXX device name that CreateFile can use // // NOTE: We\'re making an assumption here that the driver // has created a symbolic link using it\'s own name // (i.e. if the driver has the name \"XXX\" we assume // that it used IoCreateSymbolicLink to create a // symbolic link \"\\DosDevices\\XXX\". Usually, there // is this understanding between related apps/drivers. // // An application might also peruse the DEVICEMAP // section of the registry, or use the QueryDosDevice // API to enumerate the existing symbolic links in the // system. // wsprintf( completeDeviceName, TEXT(\"\\\\\\\\.\\\\%s\"), DriverName ); hDevice = CreateFile( completeDeviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hDevice == ((HANDLE)-1) ) return FALSE; // If user wants handle, give it to them. Otherwise, just close it. if ( lphDevice ) *lphDevice = hDevice; else CloseHandle( hDevice ); return TRUE; } /**************************************************************************** * * FUNCTION: UnloadDeviceDriver( const TCHAR *) * * PURPOSE: Stops the driver and has the configuration manager unload it. * ****************************************************************************/ BOOL UnloadDeviceDriver( const TCHAR * Name ) { SC_HANDLE schSCManager; schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); StopDriver( schSCManager, Name ); RemoveDriver( schSCManager, Name ); CloseServiceHandle( schSCManager ); return TRUE; } /**************************************************************************** * * FUNCTION: StopDriver( IN SC_HANDLE, IN LPCTSTR) * * PURPOSE: Has the configuration manager stop the driver (unload it) * ****************************************************************************/ BOOL StopDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) { SC_HANDLE schService; BOOL ret; SERVICE_STATUS serviceStatus; schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS ); if ( schService == NULL ) return FALSE; ret = ControlService( schService, SERVICE_CONTROL_STOP, &serviceStatus ); CloseServiceHandle( schService ); return ret; } /**************************************************************************** * * FUNCTION: RemoveDriver( IN SC_HANDLE, IN LPCTSTR) * * PURPOSE: Deletes the driver service. * ****************************************************************************/ BOOL RemoveDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) { SC_HANDLE schService; BOOL ret; schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS ); if ( schService == NULL ) return FALSE; ret = DeleteService( schService ); CloseServiceHandle( schService ); return ret; } ////////////////////install.cpp来自《Programming WDM》 // install.cpp - NT style driver install program // Copyright ?1998,1999 Chris Cant, PHD Computer Consultants Ltd // 21-Jun-99 Updated to work better in W2000b3 // ControlService SERVICE_CONTROL_INTERROGATE now fails if driver stopped // This is not a complete program void InstallDriver( CString DriverName, CString DriverFromPath) { ///////////////////////////////////////////////////////////////////////// // Get System32 directory _TCHAR System32Directory[_MAX_PATH]; if( 0==GetSystemDirectory(System32Directory,_MAX_PATH)) { AfxMessageBox(\"Could not find Windows system directory\"); return; } ///////////////////////////////////////////////////////////////////////// // Copy driver .sys file across CString DriverFullPath = System32Directory+\"\\\\Drivers\\\\\"+DriverName+\".sys\"; if( 0==CopyFile( DriverFromPath, DriverFullPath, FALSE)) // Overwrite OK { CString Msg; Msg.Format(\"Could not copy %s to %s\", DriverFullPath, Drivers); AfxMessageBox(Msg); return; } ///////////////////////////////////////////////////////////////////////// // Create driver (or stop existing driver) if( !CreateDriver( DriverName, DriverFullPath)) return; ///////////////////////////////////////////////////////////////////////// // Create/Open driver registry key and set its values // Overwrite registry values written in driver creation HKEY mru; DWORD disposition; if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\\"+DriverName, 0, \"\", 0, KEY_ALL_ACCESS, NULL, &mru, &disposition) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry key\"); return; } // Delete ImagePath RegDeleteValue(mru,\"ImagePath\"); // Delete DisplayName RegDeleteValue(mru,\"DisplayName\"); // ErrorControl DWORD dwRegValue = SERVICE_ERROR_NORMAL; if( RegSetValueEx(mru,\"ErrorControl\",0,REG_DWORD,(CONST BYTE*)&dwRegValue,sizeof(DWORD)) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry value ErrorControl\"); return; } // Start dwRegValue = SERVICE_AUTO_START; if( RegSetValueEx(mru,\"Start\",0,REG_DWORD,(CONST BYTE*)&dwRegValue,sizeof(DWORD)) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry value Start\"); return; } // Type dwRegValue = SERVICE_KERNEL_DRIVER; if( RegSetValueEx(mru,\"Type\",0,REG_DWORD,(CONST BYTE*)&dwRegValue,sizeof(DWORD)) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry value Type\"); return; } /* Examples: // DependOnGroup _TCHAR DependOnGroup[] = \"Parallel arbitrator\\0\\0\"; if( RegSetValueEx(mru,\"DependOnGroup\",0,REG_MULTI_SZ,(CONST BYTE*)&DependOnGroup,strlen(DependOnGroup)+2) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry value DependOnGroup\"); return; } // DependOnService _TCHAR DependOnService[] = \"parport\\0\\0\"; if( RegSetValueEx(mru,\"DependOnService\",0,REG_MULTI_SZ,(CONST BYTE*)&DependOnService,strlen(DependOnService)+2) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry value DependOnService\"); return; } */ RegCloseKey(mru); /* Example: ///////////////////////////////////////////////////////////////////////// // Create/Open driver\\Parameters registry key and set its values if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\\"+DriverName+\"\\\\Parameters\", 0, \"\", 0, KEY_ALL_ACCESS, NULL, &mru, &disposition) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver\\\\Parameters registry key\"); return; } // EventLogLevel dwRegValue = 1; if( RegSetValueEx(mru,\"EventLogLevel\",0,REG_DWORD,(CONST BYTE*)&dwRegValue,sizeof(DWORD)) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver\\\\Parameters registry value EventLogLevel\"); return; } // Default or No Name CString DefaultName = DriverName; int DeviceNameLen = DefaultName.GetLength()+1; LPTSTR lpDefaultName = DefaultName.GetBuffer(DeviceNameLen); if( RegSetValueEx(mru,\"\",0,REG_SZ,(CONST BYTE*)lpDefaultName,DeviceNameLen) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver\\\\Parameters default registry value\"); return; } DefaultName.ReleaseBuffer(0); RegCloseKey(mru); */ ///////////////////////////////////////////////////////////////////////// // Open EventLog\\System registry key and set its values if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\EventLog\\\\System\", 0, \"\", 0, KEY_ALL_ACCESS, NULL, &mru, &disposition) != ERROR_SUCCESS) { AfxMessageBox(\"Could not open EventLog\\\\System registry key\"); return; } // get Sources size DWORD DataSize = 0; DWORD Type; if( RegQueryValueEx(mru,\"Sources\",NULL,&Type,NULL,&DataSize) != ERROR_SUCCESS) { AfxMessageBox(\"Could not read size of EventLog\\\\System registry value Sources\"); return; } // read Sources int DriverNameLen = strlen(DriverName); DataSize += DriverNameLen+1; LPTSTR Sources = new _TCHAR[DataSize]; if( RegQueryValueEx(mru,\"Sources\",NULL,&Type,(LPBYTE)Sources,&DataSize) != ERROR_SUCCESS) { AfxMessageBox(\"Could not read EventLog\\\\System registry value Sources\"); return; } // If driver not there, add and write if( FindInMultiSz(Sources,DataSize,DriverName)==-1) { strcpy(Sources+DataSize-1,DriverName); DataSize += DriverNameLen; *(Sources+DataSize) = \'\\0\'; if( RegSetValueEx(mru,\"Sources\",0,REG_MULTI_SZ,(CONST BYTE*)Sources,DataSize) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create driver registry value Sources\"); return; } } ///////////////////////////////////////////////////////////////////////// // Create/Open EventLog\\System\\driver registry key and set its values if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\EventLog\\\\System\\\\\"+DriverName, 0, \"\", 0, KEY_ALL_ACCESS, NULL, &mru, &disposition) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create EventLog\\\\System\\\\driver registry key\"); return; } // TypesSupported dwRegValue = 7; if( RegSetValueEx(mru,\"TypesSupported\",0,REG_DWORD,(CONST BYTE*)&dwRegValue,sizeof(DWORD)) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create EventLog\\\\System\\\\driver registry value TypesSupported\"); return; } // EventMessageFile LPTSTR EventMessageFile = \"%SystemRoot%\\\\System32\\\\IoLogMsg.dll;%SystemRoot%\\\\System32\\\\Drivers\\\\\"+DriverName+\".sys\"; if( RegSetValueEx(mru,\"EventMessageFile\",0,REG_EXPAND_SZ,(CONST BYTE*)EventMessageFile,strlen(EventMessageFile)+1) != ERROR_SUCCESS) { AfxMessageBox(\"Could not create EventLog\\\\System\\\\driver registry value EventMessageFile\"); return; } RegCloseKey(mru); ///////////////////////////////////////////////////////////////////////// // Start driver service if( !StartDriver( DriverName)) return; } ///////////////////////////////////////////////////////////////////////////// BOOL CreateDriver( CString DriverName, CString FullDriver) { ///////////////////////////////////////////////////////////////////////// // Open service control manager SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if( hSCManager==NULL) { AfxMessageBox(\"Could not open Service Control Manager\"); return FALSE; } ///////////////////////////////////////////////////////////////////////// // If driver is running, stop it SC_HANDLE hDriver = OpenService(hSCManager,DriverName,SERVICE_ALL_ACCESS); if( hDriver!=NULL) { SERVICE_STATUS ss; if( ControlService(hDriver,SERVICE_CONTROL_INTERROGATE,&ss)) { if( ss.dwCurrentState!=SERVICE_STOPPED) { if( !ControlService(hDriver,SERVICE_CONTROL_STOP,&ss)) { AfxMessageBox(\"Could not stop driver\"); CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return FALSE; } // Give it 10 seconds to stop BOOL Stopped = FALSE; for(int seconds=0;seconds<10;seconds++) { Sleep(1000); if( ControlService(hDriver,SERVICE_CONTROL_INTERROGATE,&ss)==0 || ss.dwCurrentState==SERVICE_STOPPED) { Stopped = TRUE; break; } } if( !Stopped) { AfxMessageBox(\"Could not stop driver\"); CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return FALSE; } } } CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return TRUE; } ///////////////////////////////////////////////////////////////////////// // Create driver service hDriver = CreateService(hSCManager,DriverName,DriverName,SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,SERVICE_AUTO_START,SERVICE_ERROR_NORMAL, Drivers,NULL,NULL,NULL,NULL,NULL); if( hDriver==NULL) { AfxMessageBox(\"Could not install driver with Service Control Manager\"); CloseServiceHandle(hSCManager); return FALSE; } ///////////////////////////////////////////////////////////////////////// CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return TRUE; } ///////////////////////////////////////////////////////////////////////////// BOOL StartDriver( CString DriverName) { ///////////////////////////////////////////////////////////////////////// // Open service control manager SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if( hSCManager==NULL) { AfxMessageBox(\"Could not open Service Control Manager\"); return FALSE; } ///////////////////////////////////////////////////////////////////////// SC_HANDLE hDriver = OpenService(hSCManager,DriverName,SERVICE_ALL_ACCESS); if( hDriver==NULL) { AfxMessageBox(\"Could not open driver service\"); CloseServiceHandle(hSCManager); return FALSE; } SERVICE_STATUS ss; if( ControlService(hDriver,SERVICE_CONTROL_INTERROGATE,&ss)) { if( ss.dwCurrentState==SERVICE_RUNNING) { CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return TRUE; } } else if( GetLastError()!=ERROR_SERVICE_NOT_ACTIVE) { AfxMessageBox(\"Could not interrogate driver service\"); CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return FALSE; } if( !StartService(hDriver,0,NULL)) { AfxMessageBox(\"Could not start driver\"); CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return FALSE; } // Give it 10 seconds to start BOOL Started = FALSE; for(int seconds=0;seconds<10;seconds++) { Sleep(1000); if( ControlService(hDriver,SERVICE_CONTROL_INTERROGATE,&ss) && ss.dwCurrentState==SERVICE_RUNNING) { Started = TRUE; break; } } if( !Started) { AfxMessageBox(\"Could not start driver\"); CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return FALSE; } CloseServiceHandle(hDriver); CloseServiceHandle(hSCManager); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // Try to find Match in MultiSz, including Match\'s terminating \\0 int FindInMultiSz(LPTSTR MultiSz, int MultiSzLen, LPTSTR Match) { int MatchLen = strlen(Match); _TCHAR FirstChar = *Match; for(int i=0;i<MultiSzLen-MatchLen;i++) { if( *MultiSz++ == FirstChar) { BOOL Found = TRUE; LPTSTR Try = MultiSz; for(int j=1;j<=MatchLen;j++) if( *Try++ != Match[j]) { Found = FALSE; break; } if( Found) return i; } } return -1; } ///////////////////////////////////////////////////////////////////////// |
|
板凳#
发布于:2002-06-20 11:56
再次启动前用Object Viewer一看,设备对象还在,我跟踪了一下,重启服务时代码在StartServie处出来了,看来我要先看看服务状态...呵呵
|
|
地板#
发布于:2002-06-20 08:54
停止,然后删除服务整个过程应该是没有删除设备对象的 我已经测试成功了使用Service API可以动态加载、卸载内核驱动了,但是我并没有遇到你说的必须reboot才能启动服务的,在调用DeleteService之后,再次调用CreateService、StartService就可以启动了,好像必须使用ControlService读取Service状态信息判断之后才能确定服务的状态。《Undocument NT》中有一个例子InstSrv,《Programming WDM》中也有一个不太完整的例子install.cpp。 |
|
地下室#
发布于:2002-06-19 18:17
停止,然后删除服务整个过程应该是没有删除设备对象的
我们做了个东东是这样的,我的理解是没有理会DriverUnload, 结果再不reboot直接启动服务就不行了,那么就得自己动手在 停服务前删设备对象了,酱子么? |
|
5楼#
发布于:2002-06-18 15:03
虚哟阿做一些什么清楚工作呢?我就是遇到了你说得这个问题,删除只是加载了删除标记,从而导致下次加载失败。
|
|
6楼#
发布于:2002-06-18 12:03
同意zdhe
unload时必须做好相应的清理工作,否则系统不会让驱动卸载,只是做上标记此服务已删除,重新启动后不再加载此驱动。 [编辑 - 6/18/02 by fqjp] |
|
7楼#
发布于:2002-06-17 22:45
必须是NT式驱动,带PNP的不行。
------------------------ |
|
8楼#
发布于:2002-06-17 21:54
for load, there is no special request, but for unload, it does have many request.
|
|