|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)0 W4 t+ I9 i* B: J
( y9 t! i" u5 c4 B8 g8 F" V5 j这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
+ o% r1 i( h8 @8 _// 必要的头文件和要链接的LIB文件
# y- G/ l" _2 k2 |. Y( [#include <setupapi.h>
+ [7 C. N( k' A* D( a: `#include <shlwapi.h>$ B* ~* X( ?5 q' a' n4 n
#pragma comment(lib, "setupapi.lib")
! C, N5 p. T3 O3 @% \: h, V, G#pragma comment(lib, "shlwapi.lib")
$ J, m7 T' s, f% j% R- o- P# R: H2 w: J/ I; Z
// device information set(我把它译为设备信息集)
1 m- @2 R& G; a3 MHDEVINFO hDevInfo = NULL;1 Q' l$ }' | y4 d n. X( p8 P
1 Y' `% E+ j1 v" W
// 出错信息! \8 |1 S3 ~3 o" z( i6 y
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg): |3 d& H0 O( C" `4 o
{
) {6 d; i/ S3 S( T2 B4 ^ BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 5 x1 o' J* M& b4 G( f1 n7 v5 }4 c9 U
| FORMAT_MESSAGE_ALLOCATE_BUFFER,/ }, F ]% D2 i6 }+ M( ]
NULL,( `3 `' L$ C5 s; y# W7 b4 o. s
dwError,
! W7 \% U) [. x. V MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),/ s! A, ]$ ]5 l% T% \* l9 t) l# H
(LPTSTR)lpszMsg,
4 _: J; D! q4 v9 y: { 0,
; s" @. i/ I' ^8 t2 | NULL);6 H+ g5 y. `6 M9 G* Z# a# d
- {( T5 O- s& w; g: r2 R- dif (!bOk)
$ ^/ h9 d* p4 W; C/ a5 x' G{
* G( A2 o8 l S" [, v+ }( ] HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),5 }8 o2 v( H6 C
NULL,
" O0 k4 x) `" _$ G DONT_RESOLVE_DLL_REFERENCES);: C. E1 r2 w" `) p" f1 C( Y4 I5 G
if (NULL != hDll)
% i! |$ |9 Y6 O, [! a {8 L/ o+ }4 P6 w: O0 \& M
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
5 w3 H4 Y( X, M& m2 _$ Y1 L FORMAT_MESSAGE_FROM_SYSTEM,6 p% _0 h/ Z4 i* B5 y) r9 S0 x
hDll,
4 S# c: N5 p& K, E dwError,( B9 n) S/ |7 T3 {, i
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
2 m) w- E- k* x+ s* I, b (LPTSTR)lpszMsg,% b4 Q2 I- k6 L7 y! ^+ P/ d t6 c
0,; k) Q3 q Z, ~
NULL);' }& S$ x' G" k
FreeLibrary(hDll);
- M# y d2 J9 t5 C6 T; d; d% Z# \ }
# C9 M( E) S& ^7 E- E6 f% |}
# P* W% X: A9 v4 O/ Q( D& K& f}6 {1 V6 G/ S+ F- x
/ k, l6 ~1 B; v8 y1 p$ _: yBOOL ChangeStatus(DWORD NewStatus,
& B7 x" `; F) v' K* r8 q5 v9 J- Q DWORD SelectedItem, 4 C ]' m, K e0 \/ G
HDEVINFO hDevInfo)/ y6 d+ o5 ]0 y' X% K7 ]6 i! S* ?
{3 o" ?, P7 c! s3 f# ]4 L) v$ [7 d
LPTSTR lpszMsg = NULL;
* T. h7 K4 |3 j6 OHCURSOR hCursor = NULL;; N E* M. A0 ^6 m
try" a& d! N3 n1 ~, O+ y, I
{( f" Y" `! v+ [5 W x; k9 C
SP_PROPCHANGE_PARAMS PropChangeParams =
0 [0 S+ l# d5 v2 w- { {sizeof(SP_CLASSINSTALL_HEADER)};6 t6 Y6 I) z" o/ l
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; * o, g- Z. a# r/ W- b
% r- L+ F$ m9 [7 z$ Y8 t
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
3 P5 o3 D! [3 s
' a3 t1 H7 w: v: p9 m // Get a handle to the Selected Item.: {1 B9 A; u: D
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
1 Z) U* J4 I$ B2 B- u/ R7 y) r {
% u$ ~3 R/ t0 q L FormatMSG(GetLastError(), &lpszMsg);" N8 |% t* g$ R/ a+ K. X
throw lpszMsg;
: b5 C, k3 i) q7 t' c) K }
, ~; a" p+ c( ~$ g4 q; ^$ m# c/ W0 V, b. s6 O, L5 \# Y8 Z
// Set the PropChangeParams structure.4 r5 q" l* W2 A4 V
PropChangeParams.ClassInstallHeader.InstallFunction =
0 A8 x% R" V* f4 C DIF_PROPERTYCHANGE;% t2 S" I0 ^' w" H( B% H& X
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
& a2 }7 M2 n0 | C# o PropChangeParams.StateChange = NewStatus;* h7 R# z& O% d
' ]. y' v0 j6 l# ?) C" f
if (!SetupDiSetClassInstallParams(hDevInfo,
" A% _8 v6 O7 ^) i# [! } &DeviceInfoData,$ k% d4 i- I. u! U; e6 h- v" Z
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
6 v& z0 ?' z! j sizeof(PropChangeParams)))
0 J" k9 r/ V o$ A {3 g; d7 A, i& ]: x0 L( {+ Q
FormatMSG(GetLastError(), &lpszMsg);# ?% Q5 m& w, y ~1 H& j5 K
throw lpszMsg;
) X% L( B' E, W+ [5 Y }
. ~3 C& F& S+ {( U
! S( M% T3 l" ^; u( u+ b- ]/ ^ // Call the ClassInstaller and perform the change.
# W% U1 c; |, {# D/ u if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,4 C3 |" [. c: W3 T- W% @5 `
hDevInfo,
+ g& C7 Y" o- V &DeviceInfoData))5 i. }: `9 v3 N \# n; A$ `9 a
{
& N3 d4 w% f( ?; f# c: U, {1 V FormatMSG(GetLastError(), &lpszMsg);
8 P( r. h \$ x' L throw lpszMsg;' p9 {1 p) Z) @- i& }
}
+ A6 b2 H$ U, h7 f! c
j$ ^* n1 Q4 f+ O6 Q SetCursor(hCursor); c* |; \$ H- |! Q3 c
return TRUE;
, o% I! Q G4 x5 g" _( e}
4 k! M2 m! w" } d, Gcatch (TCHAR * pszError)
5 J8 M: x+ f j* K @9 H& e* U{
% o8 ]7 j! |8 E0 q' A SetCursor(hCursor);0 y- e5 [, T# ~* g) W" a: Z3 {! U) V
::MessageBox(NULL," x. {, O" B" b! a8 z0 ~0 g
pszError,
5 w$ m1 L0 X) E1 f) I( \. ]% p4 Y _T("提示"),
3 h K( y7 L# K. M% E MB_OK);& p/ \. u0 J5 n. m1 |
if (NULL != lpszMsg)9 q- k7 R( b+ [% t7 i
{
! y+ h3 e! N$ i, M) M LocalFree((HLOCAL)lpszMsg);1 L" p# g0 c% H1 s: R
}
, {& n" M, y' |) u. G return FALSE;
- B) P5 z; Y; f% x}
9 C& r4 G9 n8 K2 k/ N! P* @}
+ L7 }" G" b0 f- V
" u/ ]9 o5 L! I// 这些设备的启用和禁用主要有此函数实现
! o, H9 j; J0 z. r// 参数说明,nStatus 可取3个值,-1 :啥也不做. l: I( F3 @5 E9 l! f8 b
// 0 禁用设备,1启用设备。
& _5 o& j- r: P2 m, E) {; [+ L// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
6 L$ M8 G/ _# l! Z( n5 I: @9 y// 也是可取3个值,0 代表软驱,1 代表光驱
7 f4 a7 S$ s: v: i- |// 2 代表USB: @2 K. I( Y) E- P2 B q# L
// 譬如要对光驱实现禁用,可以这样调用此函数5 n: L3 w$ @, _8 s# s
// ControlDisk(0, 1);
8 e( _# Z: w( t: L: LBOOL ControlDisk(int nStatus, int nIndex)
" L+ T+ B1 W# D1 C8 m{. P5 e) K6 M7 k" ]; B5 v: }
if (-1 == nStatus)
9 ^8 s+ m r) M$ |# M{
% A; e( j. R* r' Z; R2 a3 e0 C return FALSE;
) s8 e+ `5 {! I' P# [# N! l}
; I+ X f8 D7 Q4 a$ P/ v( d4 F
; _1 o9 \) n& f- q* t) sLPTSTR lpszMsg = NULL;) o& S7 u$ y. @; {4 }6 \( {. w
try
- U. j; q$ W7 \; }+ Y- `- U{
b% p# {9 p! m) h" r TCHAR * GUIDString = NULL;
+ F5 [3 Y% _& }% @5 a4 x GUID guid;; k1 Q" Y j) P+ s+ m" o
ZeroMemory(&guid, sizeof(GUID));
1 r2 W) A& x# J/ F( F7 H switch(nIndex)7 E. f+ e& q7 G4 V+ p
{6 l% H" {; L! A& t x. h
case 0: // 0 代表软驱! C: |8 v- b5 j7 M* R0 S/ n: z+ a
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");5 r. ~( C- s) t* V* Y$ R+ U9 i
UuidFromString((unsigned char *)GUIDString, &guid);
6 `+ c% T' t! V break; ! f8 v- V; S2 I; O3 w
case 1: // 1 代表光驱
; @) S8 P$ X) Z8 ^. x# Z- \! X# | GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
$ _% W6 S1 V8 F0 o4 u# x R5 X UuidFromString((unsigned char *)GUIDString, &guid);. ?6 {, ^5 G2 L% K
break;
6 {1 c6 R; \" Y: A1 }2 q: s case 2: // 2 代表USB
9 C2 W( ^# M' {6 [" p$ ?/ f GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
$ E( w5 L$ `7 m UuidFromString((unsigned char *)GUIDString, &guid);$ ]2 b" Q$ b& N# k2 ?( L, _ H
break;6 d) W0 I* ] }" [8 U, b4 x3 _5 _
}
. n! K1 v( V8 V3 C
" f1 x8 E7 { H/ a0 i hDevInfo = SetupDiGetClassDevs(&guid,! x, ^$ q$ l; m; K: }4 D0 Z
NULL,/ `5 T; [% j7 o- k
NULL,( B/ o/ p/ d4 d4 L. L' a+ _
DIGCF_PRESENT);
8 E4 H E7 W& [" O5 z if (INVALID_HANDLE_VALUE == hDevInfo)
3 |2 H' C& C$ B! F0 s {3 f5 X( R8 [; ~7 @8 W
FormatMSG(GetLastError(), &lpszMsg);( k- n1 q- E: i: U+ C2 j
throw lpszMsg;
R5 B$ k. Z$ f4 K5 A S }* j* `( o( g7 \9 R& c7 z0 h+ p
( K0 R) {, @) Z6 y
DWORD i;$ [& w$ w n' u% m5 \4 _' v+ D
SP_DEVINFO_DATA DeviceInfoData;
* \) `4 d, r& J/ [, b! Z5 @, m ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));5 B1 k8 a( X" _/ m6 o/ v
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);9 o) f4 U C% \) k9 @2 z
; p! C( c8 m, ^8 N% W- \$ p+ y5 g for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i). @2 G2 Y- }0 G0 @2 T. G1 k
{7 @$ g: e% o. t1 P% \6 J) S
if (1 == nStatus)
+ K; o4 \, X1 ] {
5 k, B6 T6 x# v/ ]: c StateChange(DICS_ENABLE, i, hDevInfo);& D# {( d) |+ H
}
8 l1 Q2 }& r' g; Q/ K else if (0 == nStatus)( G2 R8 z' W {9 i0 [* t
{
. D" C% g5 F, e t StateChange(DICS_DISABLE, i, hDevInfo);
+ g5 `6 _8 N% S% H [; A } : j, Q& Q1 l2 `8 x/ s4 S; ?$ A
}0 f2 L& R4 \) |. K$ s: }: Y
0 W+ w) C, a: A/ H# m% ~ // 释放 device information set; K E9 W! h! t6 z/ j- ?
return SetupDiDestroyDeviceInfoList(hDevInfo);# a U; @ a4 T: r, J
}
- B W7 H" ?* S( i! o" }5 J* ccatch (TCHAR * pszError)
. W/ ?. _# _2 x0 \4 y{2 m3 a) O9 d/ i: U! I2 D9 f1 j; _0 p
::MessageBox(NULL,! \5 F' ?2 J6 U$ b: @7 c
pszError,
0 b" f7 ?6 F7 O6 t; y" i _T("提示"),
, V4 T' q: y L q; {: ~& y! g MB_OK);9 `% G$ \8 @' ?
if (NULL != lpszMsg)
/ M0 g" h7 u' s$ i+ B0 |' O( { {8 d6 c" x3 A. Z5 Y1 ?
LocalFree((HLOCAL)lpszMsg);
5 }: l! t$ s( r$ V8 P% s$ T }
1 X+ S3 _. }, z; B) G return FALSE; P# M- x* l7 p$ B
}
7 P" S! s/ _5 b, u0 ]return FALSE;9 h" X' {1 t( @/ U. b" ]8 ?& T/ x0 B
}
% H/ y8 F, |8 J- t
( t5 f) \! b" j2 d 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。; @1 e: T2 @' \2 d2 k
据我观察,在注册表的此项下下:
) Q6 g- l/ X1 K HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\: ?* ?' H; }' r6 f" T
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
$ D$ E8 d" \6 I! e9 j {36FC9E60-C465-11CF-8056-444553540000}& \- X# o, j/ S
这个是CDROM的( c/ d( q" N6 l i' j4 e) s" w
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
# y! I8 t) y' @: s7 w3 B& w& c这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|