|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
0 X9 U& v% w8 O! T! X) g) Z0 K e+ k: d, j6 F
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
$ _5 y6 w2 [: E* B1 b6 {% T// 必要的头文件和要链接的LIB文件
6 T( L" }. S, y: C#include <setupapi.h>& t& y. q: q3 v$ d, S n Z
#include <shlwapi.h> G1 n: `; o* p" | u
#pragma comment(lib, "setupapi.lib")( S) Q0 k# [7 Q& U! |( P8 n
#pragma comment(lib, "shlwapi.lib")3 @! |* h- B" z+ |1 t% p6 e& j8 q! Y
8 N( E- T( k+ Z$ `) ^// device information set(我把它译为设备信息集)
4 R& E2 m# n* I) H! nHDEVINFO hDevInfo = NULL; x4 X8 Q, D. v5 c4 z6 N( ^1 V
- Z( b3 I2 U2 ^$ \" E9 Q/ ~6 s// 出错信息
! q1 q2 i: ]( k3 }4 _$ T+ yvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)9 L; B% I: u+ V. K( b' G
{
4 J6 {! ?9 c# Y s5 j; O; [ BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
& v# O% G4 W9 C" w | FORMAT_MESSAGE_ALLOCATE_BUFFER,* e# P, Z8 S* x4 Q3 i. R+ S
NULL,% \0 O0 v' p" X8 |1 S; `
dwError,
2 G5 K8 e+ A, ~6 W& n$ s) s1 _ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
" A- X) ?$ C J% m (LPTSTR)lpszMsg,: ]- W9 Z' h" x4 g% {
0,
" e0 J: b9 r5 g% T. l2 V$ c NULL);
) U" H6 c; |4 q+ O9 h3 Z* q0 i+ {6 E9 @0 u
if (!bOk)
, ]4 s, U* R; G' ^5 W8 k" S* D{7 S' _9 [5 @+ b$ H! k
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
$ Y8 W: g( S4 @' h NULL,
5 @ M: u: h2 T! { DONT_RESOLVE_DLL_REFERENCES);
0 A' h5 a z' ~( U if (NULL != hDll)
3 J" I! R4 M5 w; ~2 w {
/ k0 I n; X6 g- I% X0 u FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | $ q1 D* e7 P' G, {
FORMAT_MESSAGE_FROM_SYSTEM,! q( X p( l1 k8 f3 S
hDll,
* R+ @! \$ }& c$ a dwError,3 F% o7 q6 p" |: V% l# Z
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),( F* M. l# w$ G) X' \# [) ?
(LPTSTR)lpszMsg, Q8 D$ b: V1 z. y. |. i
0,2 ]) G* `3 l4 `$ U2 ^
NULL);
* o9 A: W3 r0 Z* D( e5 z FreeLibrary(hDll);- P/ z l+ O1 j! P
}
) |* Z7 Q6 x# c* U4 V1 [2 {}
$ R. g+ a' C# G3 C; N}6 D1 W0 d) R8 ~3 ?4 ^$ i( l3 H6 R' _
6 @/ _' I, q! I; R( l G+ KBOOL ChangeStatus(DWORD NewStatus,
: I' } J4 ~* T& D2 b3 M DWORD SelectedItem, 8 k% H1 G# a& {7 w
HDEVINFO hDevInfo)
% j/ z1 C+ N# J8 w7 i{& ]/ J) P* N# Z2 c( N
LPTSTR lpszMsg = NULL;
Y' {+ z! e8 v& J R; p+ `* Z& L/ V) lHCURSOR hCursor = NULL;
% Y: D7 p. t: T( [, C4 h: I0 _try- U$ o; e f# y) s
{
( Q' p: a. r1 Y7 i& n SP_PROPCHANGE_PARAMS PropChangeParams = 3 [, t# I8 w0 t8 ~
{sizeof(SP_CLASSINSTALL_HEADER)};. e6 R$ ~$ y; I% O; ?- E( E
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
) ? H' [: P$ @) q; \6 ?+ s! h; Z
/ e7 W2 X6 V' a; {) H* F hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));! `/ [: K% G2 l' M6 H% M% ?
9 x2 ?. ?; x- j D) \: @ w9 W
// Get a handle to the Selected Item.
% a- q! q1 U! z2 u2 B if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
6 {8 c; W& L, h9 @ {; d$ f; S4 Z# s/ J+ m7 J8 \
FormatMSG(GetLastError(), &lpszMsg);
$ B+ `8 ?; P$ }' w3 l. c throw lpszMsg;" m3 T. _- U# L; e5 \3 W4 b
}2 W& I g+ Q. u+ S8 b0 ]$ ~5 H9 b
$ c0 j& m+ I2 i6 F: Y // Set the PropChangeParams structure.* r+ F" }- K8 M; q
PropChangeParams.ClassInstallHeader.InstallFunction = % e( p9 _* d( D B1 A) y8 m
DIF_PROPERTYCHANGE;
, e4 h) C) B4 M; z+ Y PropChangeParams.Scope = DICS_FLAG_GLOBAL;
( B0 a8 y3 l9 B: { M, C+ a PropChangeParams.StateChange = NewStatus;
# n& `! ]) t; u$ P# w3 S; F: n; M; W9 t9 q/ a( y% Y
if (!SetupDiSetClassInstallParams(hDevInfo,* a: h' n, t# }' {' z7 A
&DeviceInfoData,
9 p4 C; O: s# c (SP_CLASSINSTALL_HEADER *)& ropChangeParams,
) e; Y) N+ B7 T8 e+ { sizeof(PropChangeParams)))( v( s1 U/ j7 w$ i0 R4 \# G
{
8 v5 j+ e; w) x. A( o) J+ d! y FormatMSG(GetLastError(), &lpszMsg);: Y) t# P% }4 c# h. K
throw lpszMsg;1 W) K: d" D# n$ c
}/ `6 ^" m8 K1 l( t- V' C1 I
* `" L, l/ S: a% a# U% f
// Call the ClassInstaller and perform the change.2 K6 t6 k; w/ \2 g# x
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,- A5 U4 R- n" g2 U u: t
hDevInfo,
- C8 G3 Z% y" t3 ? &DeviceInfoData))
2 S3 q/ `- m7 [* t5 y2 q {
$ r% m0 {' g4 | FormatMSG(GetLastError(), &lpszMsg); W `% L2 S; `, A' ]8 O
throw lpszMsg;
6 Z; c- A5 a# I1 i u }$ f( k$ Z4 ~, W
8 R! k' }7 B& H% z: p6 E0 }: B
SetCursor(hCursor); ( n* s& L$ s6 S- Q( }5 ]/ |' Q
return TRUE;
" P$ c! p# h! u8 {} t2 A: A( f3 T. v5 K
catch (TCHAR * pszError)
1 Q9 C. d5 g7 ]$ D, i. N7 t4 Q- T{2 w# Y* v$ B0 N
SetCursor(hCursor);
, }5 p2 m) r+ F1 P) X( O3 E ::MessageBox(NULL,7 C( Q, B8 j1 n& }& Y
pszError,
+ N. Z& Z' v/ F2 p; n$ ] _T("提示"),
& N, n; L1 m: b( y+ J MB_OK);* u+ f. N& s$ I: q5 [' }
if (NULL != lpszMsg)
4 o* W$ w8 |6 R$ j# \1 j, N* _ {; s8 x) X4 B$ p* \+ b
LocalFree((HLOCAL)lpszMsg);: r: y) p) m; R* a6 }
}
* Y( Q0 \4 R! b return FALSE;9 _7 n/ ~2 k1 R& }& G
} & c+ O s0 y6 ]+ i: ^( r
}" @: d& x% P" x3 S
- o8 n! T) u9 ^" S% ~2 Z$ [
// 这些设备的启用和禁用主要有此函数实现6 n# g: T$ l) m9 t9 s+ p5 H# n
// 参数说明,nStatus 可取3个值,-1 :啥也不做
}+ F+ V+ G$ G, E// 0 禁用设备,1启用设备。7 Z: W' c+ f; X; `2 {, k2 }
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
( x% b( F; D; @. G. H! S// 也是可取3个值,0 代表软驱,1 代表光驱2 ?1 [& j1 ]/ N/ ^8 \4 R
// 2 代表USB
! r& E0 i: A( o1 ]" x9 Z// 譬如要对光驱实现禁用,可以这样调用此函数, a: f2 p0 V5 b( P3 _/ R4 |
// ControlDisk(0, 1);" g6 k/ W0 |. W# ]% j: G+ Y
BOOL ControlDisk(int nStatus, int nIndex)4 W F; z* z# Z
{: g$ v. Y5 }) W6 j [6 E& \
if (-1 == nStatus)
# p; L5 F9 _7 v. L8 |8 |3 q% X{
. ?1 A2 W7 F& F/ L! r9 b: U return FALSE;7 h; d, @! l. D9 d) @$ m- \
}
3 n; h1 _( A$ d) f# Q# t! x& L) a" T2 E+ o
LPTSTR lpszMsg = NULL;
2 G4 \3 H3 q+ }8 G0 Jtry- u$ m( g2 N/ W4 ]4 v# K! X
{4 A1 n- N5 c, J2 D# g- G
TCHAR * GUIDString = NULL;2 @' V, q1 L: w& F' q
GUID guid;
( o0 G3 d! P+ N$ B% s/ p, q ZeroMemory(&guid, sizeof(GUID));
) h* g3 h8 P, d3 G/ E/ e switch(nIndex)
; n. t$ H$ G" `1 j! y5 [+ v+ B7 u {5 C9 K$ [) P' u/ M6 S- r
case 0: // 0 代表软驱
& J: \' d- t& h- ]2 F" H" ~ e GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
' a. W6 i$ h n" n UuidFromString((unsigned char *)GUIDString, &guid);% o* f1 {% d }1 ?. z
break; ( @& T0 t7 O& ^3 {% r" e0 O1 b
case 1: // 1 代表光驱
1 Y# D) ~* f; E9 } H GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
2 _: C$ ?: e) @4 W! I UuidFromString((unsigned char *)GUIDString, &guid);
# I! l# h, ~& q2 C, Z break;( B" W u4 s! X' M
case 2: // 2 代表USB
& F' f5 U! B+ [9 B, I# d GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
' z; t0 p% T5 m% C: v1 i& I UuidFromString((unsigned char *)GUIDString, &guid);
^4 _5 l! X7 B/ Z break;: N& M4 w3 ~3 r* w5 m! R2 A
}1 k3 z2 [- T0 ^7 _/ V' Z
~" `4 v1 n% R7 U8 G hDevInfo = SetupDiGetClassDevs(&guid,/ K& Z) C9 A9 i: x- V1 P
NULL,- r$ ^# |' ?! V- a9 p
NULL,
* L x) c% B5 x, s: B0 r7 n DIGCF_PRESENT);: u, J( n- Y$ H
if (INVALID_HANDLE_VALUE == hDevInfo)) ]: x3 {. k$ O1 M% S1 K
{7 J$ r8 M1 F' Z0 B- ^' q7 i
FormatMSG(GetLastError(), &lpszMsg);
( c& ~) |. U& ~/ T& R1 u throw lpszMsg;
& I: W) z6 k5 K# K4 g }
8 A7 q: z t7 |% `' E6 u9 a |( V4 o# P3 S& U
DWORD i;% o8 q' \8 o; h
SP_DEVINFO_DATA DeviceInfoData;; o* x% G' _2 ^" P* ~
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
% g7 u x; I) P, t: b7 \0 _- q' _5 t DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);# N; y9 S% k" B* L/ v% ]
% c4 [' H% ?* w. i
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)8 m7 e! _: R2 E3 [8 h8 {9 z1 K
{; w, b a* o* i
if (1 == nStatus)& j: |) t: L/ s- V0 c
{: a" ?2 R; [+ b: P. F+ y
StateChange(DICS_ENABLE, i, hDevInfo);
8 i; k; c7 w6 g' q2 L8 Q }
9 [+ N: V4 c, w1 A) { else if (0 == nStatus)
: Y0 J; B; d6 j' _( n {. ^9 j Z6 y3 X4 K2 }
StateChange(DICS_DISABLE, i, hDevInfo);; ~6 h/ O; c7 Y Y! H9 o5 T3 X1 b; R
} 1 F9 V' P- s) ]6 v- i
}9 q _' u. U* K0 l9 ~. k; W
2 W9 t* r. I. a1 n // 释放 device information set( t, w- b+ e3 @0 Z- N& ]- S, t
return SetupDiDestroyDeviceInfoList(hDevInfo);) n0 u& D& y- G
}0 F; Z$ ^; Z% u5 z A% k& Y9 M. v
catch (TCHAR * pszError)
3 m; Z3 R# f! O{9 o8 a! X6 H$ k$ c/ M
::MessageBox(NULL,
$ L3 F% m0 s/ Y5 z+ Y3 ]5 @2 h. e pszError,
: M' v. d& K/ L. y4 P _T("提示"),
! h& M+ U- R3 ?* I* d3 V2 ~% z8 n MB_OK);
' d6 v. V, w! p6 N9 z if (NULL != lpszMsg)
* O5 u% w5 R/ |; X& j {! ~% Q* B+ F( _* l- _
LocalFree((HLOCAL)lpszMsg);' ~( k+ s4 z6 o& _* k
}
. E7 u8 M6 R$ \9 [ return FALSE;
2 d$ a C' }8 q}3 r% Y! ]" H1 ]! C h7 T9 O* J+ Y
return FALSE;
1 [: w2 z2 ?9 P9 R& B8 u}
; X2 x5 q, ]0 |% v- T0 g0 D* L' u
4 b; ` S1 P/ l8 S7 ?$ M& j, N 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
( Q4 L2 S! b. J6 ^ 据我观察,在注册表的此项下下:8 R( o/ [( G t% V* e6 e' i2 `
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
, O" [' j/ H. [+ i 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
) o, K0 L) Z4 }7 u# Q8 G9 p0 \ {36FC9E60-C465-11CF-8056-444553540000}9 t- ?9 {) V5 @7 y# ^- O) u! W. h! o2 K
这个是CDROM的3 v. s, @$ J+ x! w- U
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
% I! _% N4 K. v这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|