山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他デバイスドライバをインストール・アンインストールするプログラム
概要
デバイスドライバのファイル名を指定してデバイスドライバのインストールおよびアンインストールするプログラムです。
デバイスドライバの操作には管理者権限が必要なのでプログラムを実行すると管理者権限を要求します。
デバイスドライバの操作には管理者権限が必要なのでプログラムを実行すると管理者権限を要求します。
テスト環境
コンパイラ
Visual C++ 2008/2013 Express 32/64bit マルチバイト/UNICODE実行環境
Windows 7 Enterprise 64bitWindows 8.1 Enterprise 64bit
Windows XP Professional Service Pack 3 32bit
Windows Vista Ultimate Service Pack 2 32bit
Windows 7 Professional Service Pack 1 32bit
プログラムソースの概要
_tWinMain
ダイアログボックスを表示します。DlgProc1
ダイアログボックスのプロシージャです。WM_INITDIALOG
ダイアログボックスの初期化時に呼び出されます。ドライバパス・ドライバ名のエディットボックスの初期値を設定します。
WM_COMMAND
IDC_LOAD_BUTTON
ドライバロードボタンをクリックしたときに呼び出されます。ドライバパス・ドライバ名のエディットボックスの文字列を取得し、adddrv関数を呼び出し、ドライバをインストールします。
IDC_UNLOAD_BUTTON
ドライバアンロードボタンをクリックしたときに呼び出されます。ドライバパス・ドライバ名のエディットボックスの文字列を取得し、deldrv関数を呼び出し、ドライバをアンインストールします。
IDC_REF_BUTTON
ファイル参照ボタンをクリックした場合に呼び出されます。GetFileName関数を呼び出しドライバファイルのフルパス名を取得します。
フルパス名からフォルダー名を除いたファイル名の先頭位置と拡張子の位置を取得します。
上記で取得した位置から拡張子を除いたファイル名のみを取得します。
フルパス名とファイル名をドライバパス・ドライバ名のエディットボックスに設定します。
IDCANCEL
EndDialogによりダイアログボックスを終了します。adddrv
ドライバのフルパス名とファイル名よりドライバをインストールします。一回インストールすると再起動しても有効です。
OpenSCManager APIによりサービスコントロールマネージャーを開きサービスコントロールマネージャーのデータベースのハンドル取得します。
正常に開けない場合は、error_dialog関数によりエラーメッセージを表示して関数を終了します。
OpenService APIによりドライバサービスのハンドルを取得します。
ドライバサービスのハンドルが取得できない場合は、CreateService APIによりドライバサービスを作成しハンドルを取得します。
ドライバサービスの作成に失敗した場合は、error_dialog関数によりエラーメッセージを表示してデータベースのハンドルを閉じて関数を終了します。
StartService APIによりドライバサービスを開始させます。
ドライバサービスの開始に失敗した場合は、error_dialog関数によりエラーメッセージを表示してドライバサービスのハンドルとデータベースのハンドルを閉じて関数を終了します。
ドライバーサービスの開始に成功した場合は、ドライバサービスのハンドルとデータベースのハンドルを閉じて関数を終了します。
以降、他のプログラムからドライバを使用することができます。
deldrv
ドライバのフルパス名とファイル名よりドライバをインストールします。一回インストールすると再起動しても有効です。
OpenSCManager APIによりサービスコントロールマネージャーを開きサービスコントロールマネージャーのデータベースのハンドル取得します。
正常に開けない場合は、error_dialog関数によりエラーメッセージを表示して関数を終了します。
OpenService APIによりドライバサービスのハンドルを取得します。
ドライバサービスの取得に失敗した場合は、error_dialog関数によりエラーメッセージを表示してデータベースのハンドルを閉じて関数を終了します。
ControlService APIによりドライバサービスを停止させます。
DeleteServiceによりドライバを解放します。
ドライバサービスのハンドルとデータベースのハンドルを閉じて関数を終了します。
GetFileName
GetOpenFileName APIによりファイル名を取得するコモンダイアログボックスを表示しファイル名を取得します。error_dialog
FormatMessage APIによりエラーコードに対応するエラーメッセージを取得します。エラーメッセージの文字列バッファは、FormatMessage APIにより動的に確保されます。
MessageBox APIによりエラーメッセージを表示します。
LocalFree APIにより文字列バッファを解放します。
プログラムに管理者権限を要求するようにマニフェストを修正
Visual C++のプロジェクトのプロパティを開き、構成のプロパティの中のリンカ・マニフェストファイルを選びます。
UACの実行レベルをrequireAdministratorに変更します。
UACの実行レベルをrequireAdministratorに変更します。
ソースコード
drvinst.cpp
#include <windows.h>
#include <tchar.h>
#include "resource.h"
#define DRIVER_PATH _TEXT("C:\\beeptest.sys")
#define DRIVER_NAME _TEXT("beeptest")
// ダイアログボックスプロシージャー
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
// ドライバをインストールする
BOOL adddrv(TCHAR* DriverId, TCHAR* DriverPath);
// ドライバをアンインストールする
BOOL deldrv(TCHAR* DriverId, TCHAR* DriverPath);
// 読込ファイル名の取得
BOOL GetFileName(HWND hWnd, TCHAR* fname, int sz);
// エラーコードからエラーメッセージを作成しダイアログボックスに表示
void error_dialog(HWND hWnd, int errorcode);
HWND hDlg;
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst, TCHAR* lpszCmdLine, int nCmdShow){
DialogBox(hInstance, TEXT("DLG1"), 0, (DLGPROC)DlgProc1);
return 0;
}
// ダイアログボックスプロシージャー
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
TCHAR driver_path[MAX_PATH];
TCHAR driver_name[MAX_PATH];
TCHAR* top,*bottom;
switch (msg) {
case WM_INITDIALOG:
::hDlg = hDlg;
SetWindowText(GetDlgItem(hDlg, IDC_PATH_EDIT), DRIVER_PATH);
SetWindowText(GetDlgItem(hDlg, IDC_NAME_EDIT), DRIVER_NAME);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_LOAD_BUTTON:
GetWindowText(GetDlgItem(hDlg, IDC_PATH_EDIT), driver_path,sizeof(driver_path)/sizeof(TCHAR));
GetWindowText(GetDlgItem(hDlg, IDC_NAME_EDIT), driver_name, sizeof(driver_name) / sizeof(TCHAR));
if (adddrv(driver_name, driver_path) == TRUE)
MessageBox(hDlg, _TEXT("ドライバーがインストールされました"), _TEXT("情報"), MB_OK);
else
MessageBox(hDlg, _TEXT("ドライバーがインストールできませんでした"), _TEXT("エラー"), MB_OK);
return TRUE;
case IDC_UNLOAD_BUTTON:
GetWindowText(GetDlgItem(hDlg, IDC_PATH_EDIT), driver_path, sizeof(driver_path) / sizeof(TCHAR));
GetWindowText(GetDlgItem(hDlg, IDC_NAME_EDIT), driver_name, sizeof(driver_name) / sizeof(TCHAR));
if(deldrv(driver_name, driver_path)==TRUE)
MessageBox(hDlg, _TEXT("ドライバーがアンインストールされました"), _TEXT("情報"), MB_OK);
else
MessageBox(hDlg, _TEXT("ドライバーをアンインストールできませんでした"), _TEXT("エラー"), MB_OK);
return TRUE;
case IDC_REF_BUTTON:
if (GetFileName(hDlg, driver_path, sizeof(driver_path) / sizeof(TCHAR))){
top = _tcsrchr(driver_path, _T('\\'));
bottom = _tcsrchr(driver_path, _T('.'));
if (_tcscmp(bottom + 1, _TEXT("sys")) == 0){ // 拡張子チェック
if (top < bottom){
_tcsncpy_s(driver_name, sizeof(driver_name) / sizeof(TCHAR), top + 1, bottom - top - 1);
}
}
SetWindowText(GetDlgItem(hDlg, IDC_PATH_EDIT), driver_path);
SetWindowText(GetDlgItem(hDlg, IDC_NAME_EDIT), driver_name);
}
return TRUE;
case IDCANCEL:
EndDialog(hDlg, FALSE);
return FALSE;
default:
return FALSE;
}
default:
return FALSE;
}
return TRUE;
}
// ドライバをインストールする
BOOL adddrv(TCHAR* DriverId, TCHAR* DriverPath){
SC_HANDLE hSCManager;
SC_HANDLE hService;
// サービスコントロールマネージャーを開く
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCManager == NULL){
DWORD dwError = GetLastError();
error_dialog(hDlg, dwError);
return FALSE; // サービスコントロールマネージェーが開けない
}
hService = OpenService(hSCManager, DriverId, SERVICE_ALL_ACCESS);
if (hService == 0){
// ドライバサービスを生成
hService = CreateService(hSCManager, DriverId, DriverId,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DriverPath,
NULL, NULL, NULL, NULL, NULL);
if (hService == NULL){
DWORD dwError = GetLastError();
error_dialog(hDlg, dwError);
CloseServiceHandle(hSCManager);
return FALSE;
}
}
if (StartService(hService, 0, NULL) == FALSE){
DWORD dwError = GetLastError();
//サービスのインスタンスはすでに動作している以外のエラー
if (dwError != ERROR_SERVICE_ALREADY_RUNNING){
error_dialog(hDlg, dwError);
DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return FALSE;
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return TRUE;
}
// ドライバをアンインストールする
BOOL deldrv(TCHAR* DriverId, TCHAR* DriverPath){
SC_HANDLE hSCManager;
SC_HANDLE hService;
// サービスコントロールマネージャーを開く
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCManager == NULL){
DWORD dwError = GetLastError();
error_dialog(hDlg, dwError);
return FALSE; // サービスコントロールマネージェーが開けない
}
hService = OpenService(hSCManager, DriverId, SERVICE_ALL_ACCESS);
if (hService == 0){
DWORD dwError = GetLastError();
error_dialog(hDlg, dwError);
CloseServiceHandle(hSCManager);
return FALSE;
}
SERVICE_STATUS status;
ControlService(hService, SERVICE_CONTROL_STOP, &status);
DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return TRUE;
}
// 読込ファイル名の取得
BOOL GetFileName(HWND hWnd,TCHAR* fname, int sz){
OPENFILENAME o;
fname[0] = _T('\0');
ZeroMemory(&o, sizeof(o));
o.lStructSize = sizeof(o);
o.hwndOwner = hWnd;
o.Flags = 0;
o.lpstrFile = fname;
o.nMaxFile = sz;
o.lpstrFilter = _TEXT("SYS(*.SYS)\0");
o.nFilterIndex = 1;
return GetOpenFileName(&o);
}
// エラーコードからエラーメッセージを作成しダイアログボックスに表示
void error_dialog(HWND hWnd, int errorcode){
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);
MessageBox(hWnd, (LPCTSTR)lpMsgBuf, _TEXT("エラー"), MB_OK | MB_ICONINFORMATION);
LocalFree(lpMsgBuf);
}
resource.h
#define IDC_PATH_EDIT 100
#define IDC_NAME_EDIT 102
#define IDC_LOAD_BUTTON 110
#define IDC_UNLOAD_BUTTON 112
#define IDC_REF_BUTTON 114
resource.rc
#include <windows.h>
#include "resource.h"
DLG1 DIALOG DISCARDABLE 0, 0, 498, 97
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT
CAPTION "ドライバのロード/アンロード"
FONT 9, "MS 明朝"
{
CONTROL "ドライバパス", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 7, 81, 12
CONTROL "", IDC_PATH_EDIT, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL, 7, 19, 484, 12
CONTROL "ドライバ名", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 38, 65, 12
CONTROL "", IDC_NAME_EDIT, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL, 7, 50, 114, 12
CONTROL "ドライバロード(&L)", IDC_LOAD_BUTTON, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 7, 76, 103, 14
CONTROL "ドライバアンロード(&R)", IDC_UNLOAD_BUTTON, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 120, 76, 128, 14
CONTROL "ファイル参照(&B)", IDC_REF_BUTTON, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 255, 76, 96, 14
}
Copyright (C) 2012 山本ワールド All Rights Reserved.