這個月有個工作是要用隊友給的driver去對某個設備做I/O操作控制,不過這幾天發現有時DriverMonitor掛驅動有的路徑會有問題,看call CreateService建在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services的登錄檔ImagePath可能因為編碼問題有點錯誤,也懶得寫INF而且我不太會用工具產生XD,還有個問題我不知道是什麼原因,用看系統service運作的工具理應掛載的測試driver應該不存在了,可是似乎無法重新用DriverMonitor啟動,非得重新開機才可以,前天為了這幾個問題還花幾小時去re DriverMonitor研究幾個function,不過看不出來流程有什麼差異或問題,但還是自己寫了一個常規Loader去處理...話說隊友給的driver還是一直有問題對I/O寫資料給設備有時還是會BSoD.........Orz
DriverLoader.h
#ifndef __DRIVER_LOADER__
#define __DRIVER_LOADER__
#include <wx/wx.h>
#include <wx/listctrl.h>
#include <windows.h>
#include "fileopen.xpm"
#include "start.xpm"
#include "stop.xpm"
enum{
ID_START = 100,
ID_STOP
};
enum{
COLUMN_0 = 0
};
class App:public wxApp
{
public:
bool OnInit();
};
class MSGList:public wxListCtrl
{
public:
MSGList(wxWindow*);
void AddMessage(const wxString&);
private:
int item_num;
};
class Frame:public wxFrame
{
public:
Frame(const wxString&,const wxSize&);
void OnOpenDriver(wxCommandEvent&);
void OnStartDriver(wxCommandEvent&);
void OnStopDriver(wxCommandEvent&);
void OnExit(wxCommandEvent&);
private:
void CreateUI();
MSGList *msg;
wxString name;
wxString path;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(Frame,wxFrame)
EVT_MENU(wxID_OPEN,Frame::OnOpenDriver)
EVT_MENU(wxID_EXIT,Frame::OnExit)
EVT_MENU(ID_START,Frame::OnStartDriver)
EVT_MENU(ID_STOP,Frame::OnStopDriver)
END_EVENT_TABLE()
#endif
DriverLoader.cpp
#include "DriverLoader.h"
DECLARE_APP(App)
IMPLEMENT_APP(App)
bool App::OnInit()
{
Frame *frame = new Frame(wxT("wxDriverLoader"),wxSize(600,400));
frame->Show(true);
return true;
}
Frame::Frame(const wxString &title,const wxSize &size):wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,size,wxMINIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxSYSTEM_MENU)
{
CreateUI();
}
void Frame::CreateUI()
{
wxMenu *file = new wxMenu;
file->Append(wxID_OPEN,wxT("O&pen\tAlt-o"),wxT("Open Driver"));
file->AppendSeparator();
file->Append(ID_START,wxT("S&tart\tAlt-r"),wxT("Start Driver"));
file->Append(ID_STOP,wxT("S&top\tAlt-s"),wxT("Stop Driver"));
file->AppendSeparator();
file->Append(wxID_EXIT,wxT("E&xit\tAlt-q"),wxT("Exit"));
wxMenuBar *bar = new wxMenuBar;
bar->Append(file,wxT("file"));
wxToolBar *tool = new wxToolBar(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTB_HORIZONTAL | wxNO_BORDER);
wxBitmap open_bmp(fileopen_xpm);
wxBitmap start_bmp(start_xpm);
wxBitmap stop_bmp(stop_xpm);
tool->AddTool(wxID_OPEN,open_bmp,wxT("Open Driver"));
tool->AddTool(ID_START,start_bmp,wxT("Start Driver"));
tool->AddTool(ID_STOP,stop_bmp,wxT("Stop Driver"));
tool->Realize();
SetToolBar(tool);
msg = new MSGList(this);
SetMenuBar(bar);
CreateStatusBar(2);
}
void Frame::OnOpenDriver(wxCommandEvent &event)
{
msg->AddMessage(wxT("********************Driver Select!********************"));
wxFileDialog dlg(this,wxT("Select File"),wxT("."),wxT("*.sys"),wxT("SYS files (*.sys)|*.sys"),wxOPEN);
if(dlg.ShowModal() == wxID_OK){
name = dlg.GetFilename();
path = dlg.GetPath();
wxString str;
str.Printf(wxT("Open File %s Success!"),name);
msg->AddMessage(str);
}
else{
msg->AddMessage(wxT("Open File Fail!"));
}
}
void Frame::OnStartDriver(wxCommandEvent &event)
{
msg->AddMessage(wxT("********************Load Driver!********************"));
DWORD error = 0;
SC_HANDLE mgr = NULL;
mgr = OpenSCManagerW(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(mgr == NULL){
wxString str;
str.Printf(wxT("OpenSCManager Error:%d"),error);
msg->AddMessage(str);
CloseServiceHandle(mgr);
return;
}
else{
msg->AddMessage(wxT("OpenSCManager Success!"));
}
SC_HANDLE ddk = NULL;
ddk = CreateServiceW(mgr,name.wc_str(),name.wc_str(),SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,
path.wc_str(),NULL,NULL,NULL,NULL,NULL);
if(ddk ==NULL){
error = GetLastError();
if((error != ERROR_IO_PENDING) && (error != ERROR_SERVICE_EXISTS)){
wxString str;
str.Printf(wxT("CreateService Error:%d"),error);
msg->AddMessage(str);
CloseServiceHandle(mgr);
return;
}
ddk = OpenService(mgr,name.wc_str(),SERVICE_ALL_ACCESS);
if(ddk == NULL){
error = GetLastError();
wxString str;
str.Printf(wxT("OpenService Error Code:%d"),error);
msg->AddMessage(str);
CloseServiceHandle(mgr);
return;
}
else{
msg->AddMessage(wxT("OpenService Success!"));
}
}
else{
msg->AddMessage(wxT("CreateService Success!"));
}
error = StartServiceW(ddk,NULL,NULL);
if(!error){
error = GetLastError();
if((error != ERROR_IO_PENDING) && (error != ERROR_SERVICE_EXISTS)){
wxString str;
str.Printf(wxT("StartService Error:%d"),error);
msg->AddMessage(str);
CloseServiceHandle(mgr);
CloseServiceHandle(ddk);
return;
}
else{
if(error == ERROR_IO_PENDING){
msg->AddMessage(wxT("StartService ERROR_IO_PENDING!"));
CloseServiceHandle(mgr);
CloseServiceHandle(ddk);
return;
}
else{
msg->AddMessage(wxT("StartService Fail ERROR_SERVICE_ALREADY_RUNNING!"));
CloseServiceHandle(mgr);
CloseServiceHandle(ddk);
return;
}
}
}
else{
msg->AddMessage(wxT("StartService Success!"));
}
if(mgr){
CloseServiceHandle(mgr);
}
if(ddk){
CloseServiceHandle(ddk);
}
}
void Frame::OnStopDriver(wxCommandEvent &event)
{
msg->AddMessage(wxT("********************Unload Driver!********************"));
DWORD error = 0;
SC_HANDLE mgr = NULL;
mgr = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(mgr == NULL){
wxString str;
str.Printf(wxT("OpenSCManager Error:%d"),error);
msg->AddMessage(str);
return;
}
else{
msg->AddMessage(wxT("OpenSCManager Success!"));
}
SC_HANDLE ddk = NULL;
ddk = OpenService(mgr,name.wc_str(),SERVICE_ALL_ACCESS);
if(ddk == NULL){
error = GetLastError();
wxString str;
str.Printf(wxT("OpenService Error Code:%d"),error);
msg->AddMessage(str);
CloseServiceHandle(mgr);
return;
}
else{
msg->AddMessage(wxT("OpenService Success!"));
}
SERVICE_STATUS status;
if(!ControlService(ddk,SERVICE_CONTROL_STOP,&status)){
error = GetLastError();
wxString str;
str.Printf(wxT("ControlService Error Code:%d"),error);
msg->AddMessage(str);
}
else{
msg->AddMessage(wxT("ControlService Success!"));
}
if(!DeleteService(ddk)){
error = GetLastError();
wxString str;
str.Printf(wxT("DeleteService Error Code:%d"),error);
msg->AddMessage(str);
}
else{
msg->AddMessage(wxT("DeleteService Success!"));
}
if(mgr){
CloseServiceHandle(mgr);
}
if(ddk){
CloseServiceHandle(ddk);
}
}
void Frame::OnExit(wxCommandEvent &event)
{
Close();
}
MSGList::MSGList(wxWindow *parent):wxListCtrl(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLC_REPORT | wxLC_SINGLE_SEL)
{
item_num = 0;
wxListItem item;
item.SetText(wxT("Message"));
InsertColumn(COLUMN_0,item);
SetColumnWidth(COLUMN_0,600);
}
void MSGList::AddMessage(const wxString &msg)
{
InsertItem(item_num,msg,COLUMN_0);
++item_num;
}
測試用
TestDriver.cpp
extern "C"{
#include <ntddk.h>
}
void Unload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING Win32Device;
DbgPrint("Unload Driver!\n");
RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\TestDriver");
IoDeleteSymbolicLink(&Win32Device);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS Create(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgPrint("Create Device\n");
return STATUS_SUCCESS;
}
NTSTATUS Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgPrint("Close Device\n");
return STATUS_SUCCESS;
}
NTSTATUS DefaultHandler(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgPrint("Default Handler\n");
return Irp->IoStatus.Status;
}
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceName,Win32Device;
PDEVICE_OBJECT DeviceObject = NULL;
NTSTATUS status;
DbgPrint("Load Driver!\n");
RtlInitUnicodeString(&DeviceName,L"\\Device\\TestDriver");
RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\TestDriver");
for(unsigned i = 0;i <= IRP_MJ_MAXIMUM_FUNCTION;++i){
DriverObject->MajorFunction[i] = DefaultHandler;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Close;
DriverObject->DriverUnload = Unload;
status = IoCreateDevice(DriverObject,10,&DeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
if(!NT_SUCCESS(status)){
return status;
}
if(!DeviceObject){
return STATUS_UNEXPECTED_IO_ERROR;
}
DeviceObject->Flags |= DO_DIRECT_IO;
status = IoCreateSymbolicLink(&Win32Device,&DeviceName);
DriverObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
測試用
UserLayer.cpp
#include <windows.h>
#include <tchar.h>
#include <cstdio>
int main(void)
{
HANDLE h = CreateFile(_T("\\\\.\\TestDriver"),GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(h == INVALID_HANDLE_VALUE){
printf("CreateFile Failed!\n");
return -1;
}
else{
printf("CreateFile Success!\n");
}
CloseHandle(h);
getchar();
return 0;
}
沒有留言:
張貼留言