|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
3 Z! b0 L4 {5 H$ k; ?
; Q8 s2 m" f/ [1 P7 n" r/ k) ?这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:% Y0 ?' ^9 W* K4 L: f
// 必要的头文件和要链接的LIB文件1 b3 T& }/ r! i, o
#include <setupapi.h>7 ~8 V+ t5 s$ m# ?- R( m: _
#include <shlwapi.h>
, Y5 ~; K/ u; l#pragma comment(lib, "setupapi.lib")
2 {+ u* M0 T0 x3 _" `6 x#pragma comment(lib, "shlwapi.lib")
+ a, G7 e9 O4 a9 G( {' ?$ W3 N2 Q) u+ Q/ W+ u# w! ^/ e
// device information set(我把它译为设备信息集)
0 A/ O6 a: O, G, RHDEVINFO hDevInfo = NULL;0 V9 L/ _: o! f: h- J# m
4 b7 R8 W- W f5 A- ^1 Q5 }
// 出错信息
$ X& }+ l3 F7 n) P; Xvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)& t6 w: e& I. V8 }, a* v
{ : m# F f& s, ~3 Z3 u2 H: C! u
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM : W5 O/ x/ I8 m/ ?6 P2 s
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
& o' |' F5 S0 a NULL,: d2 c5 |8 d/ B- x5 W+ ^2 F
dwError,! K2 W) ?& j$ x' k
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
% e1 w! | X$ M# K+ C! B (LPTSTR)lpszMsg,; P# R$ {6 I, R2 q8 c
0,
1 ^& j- M( R! y- z NULL);
* G4 M0 O S9 g3 d- ~
5 b% R1 B4 V3 x6 z" E# K0 [0 t2 xif (!bOk)# h- z( x5 o( Q
{3 N3 y+ u( M3 n. D/ M; |2 f
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),2 u+ i. [- X- Y& C: t( B+ \3 d- ^7 g
NULL,! R0 a% T. ?& _. P, z# W
DONT_RESOLVE_DLL_REFERENCES);
2 b; C* s* c; V/ K if (NULL != hDll)( g1 Z8 G$ B; w4 k: M0 j0 g r4 {
{
" D% ^ K) x+ U' j- m3 \& F* ~* f4 O9 \ FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | 3 r" E% \& X) U2 ]: {9 _) b
FORMAT_MESSAGE_FROM_SYSTEM,$ R5 i. p! d9 i, k# Y" l$ @: B
hDll,
' ^2 x1 P+ A8 l dwError,
x+ g9 Q$ I1 | MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
6 Q4 f7 z Q E6 O (LPTSTR)lpszMsg,
& i( u' E, h6 s( _) r% ` 0,8 a' m4 X# s# b; E O& v \
NULL);
: \7 q4 n- _6 T6 y7 r. H FreeLibrary(hDll);% F. X7 }3 i, p% {- _1 W
}9 H, P" U; o% h9 R( e
}
8 j$ O* s: I9 z8 k}: \7 z, n6 O. B
' m9 b8 G [& K
BOOL ChangeStatus(DWORD NewStatus,
* ]( |9 P4 |, i+ [ DWORD SelectedItem,
3 h; X! n& w+ M- r2 Z HDEVINFO hDevInfo)
& g1 ]+ k* B% ^7 I. b{1 s" A- Y! c% v& t
LPTSTR lpszMsg = NULL;
* p. O5 Z. [3 u0 D. z& e5 EHCURSOR hCursor = NULL;
; S/ s. Z# q3 Rtry4 @$ f: H+ s7 m* B% D0 V
{
# D5 P# s% C' E! J; h3 h4 t SP_PROPCHANGE_PARAMS PropChangeParams = ) t! p$ t; I' _ z j
{sizeof(SP_CLASSINSTALL_HEADER)};
# B3 N0 u3 i4 T- g" i SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
- f& W+ ]- Y, I* F* x- z1 N! E% H# }; _
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));% e# H7 P" R: |
, @# f4 v: r. M" a
// Get a handle to the Selected Item.1 Q% m+ E+ w9 a; N3 c+ H" C2 D
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))9 U s' N. v& j3 m
{6 |2 K! H- s' [! e8 [$ g
FormatMSG(GetLastError(), &lpszMsg);5 x+ r) c: A( n e: v
throw lpszMsg;
0 Q2 s& X+ F5 S8 s }1 S0 R2 J; l! Y+ c3 E6 I* v
8 {. T# ?7 r9 X // Set the PropChangeParams structure.% M' l9 P$ I v3 [# _
PropChangeParams.ClassInstallHeader.InstallFunction =
3 M& N" W- P; ~$ a' {! | DIF_PROPERTYCHANGE;6 p7 p8 g8 _+ g8 D6 G' R' g
PropChangeParams.Scope = DICS_FLAG_GLOBAL;6 y- y9 V. q& `4 A
PropChangeParams.StateChange = NewStatus;
6 Q7 P! m; C' t; s5 R
4 \+ ^: v: e, U1 }2 P4 h- E& z; W4 b if (!SetupDiSetClassInstallParams(hDevInfo,; g: ~2 L3 l, Q! ?1 l
&DeviceInfoData,
- j! j f1 e$ o' r$ }2 E! T (SP_CLASSINSTALL_HEADER *)& ropChangeParams,( W: C; k5 O u: P8 W
sizeof(PropChangeParams))), _1 x8 C8 C# Q3 X
{+ }3 G* [* n3 b4 E
FormatMSG(GetLastError(), &lpszMsg);0 Y8 n8 t5 _" E, Q, }+ u, V
throw lpszMsg;# W7 w$ q" z6 W1 e+ x
}& p3 Y* E2 A4 j0 Q' S
' | ]( X- h( M& g& L
// Call the ClassInstaller and perform the change.
- l& M2 V/ ?7 x" x7 X( `5 ? if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
A2 e+ P+ w+ J7 ^ hDevInfo,
9 o# R+ O% Z( n2 R s6 e &DeviceInfoData))
, p1 B4 T8 V$ A( ?% ? {
$ {5 t( P" o. x' D- Z FormatMSG(GetLastError(), &lpszMsg);
9 [" K: p0 s% m' w$ l, W0 K throw lpszMsg;
: B4 ~! e( d. w; S$ I! I% H }
+ Y7 b7 ]% A* g+ _& z
" F. ?5 D+ M2 P3 ~5 U. O SetCursor(hCursor); 2 I; |. W6 A- E% Q% `
return TRUE;/ k/ n- s# T) r9 e% \5 s0 U
}/ J( L1 P' P- m
catch (TCHAR * pszError)
" ]- w; q, E8 |" Q" n{
, t7 T$ L! e$ l% }) l! {# t* B SetCursor(hCursor);7 r% D- _' v. p1 \3 F5 c `7 C
::MessageBox(NULL,( b& M' k3 A P, I' c* K2 d6 y1 J2 n
pszError,/ F' V( t0 L% x' |! ^ V! X
_T("提示"),
; n6 |# V8 Y% Q) G2 e MB_OK);
. Q+ r" ^! ]) ~$ F if (NULL != lpszMsg) L) N) o( M2 f2 F* L! H
{5 H& b$ Z* K4 P' \% a
LocalFree((HLOCAL)lpszMsg);
) X5 o8 |' M$ u. N/ } }
6 |" ]4 S- ~& K4 `& P/ \+ P. h8 _ return FALSE;
/ {1 ^3 ^8 J, U0 I2 T, W1 x}
8 _6 f; F9 s, }/ V& ]* r}: r: d& @, s5 y7 a- h" U
; v& {7 l, Z# ~$ a// 这些设备的启用和禁用主要有此函数实现
/ ^7 |# R% B7 G: V// 参数说明,nStatus 可取3个值,-1 :啥也不做8 N& d" p) {% q p# k: R7 Q
// 0 禁用设备,1启用设备。
0 |8 q J& e) J$ d' e# T' X+ _// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
! H# y' b+ o" C// 也是可取3个值,0 代表软驱,1 代表光驱- M, f3 q$ r/ W- N
// 2 代表USB$ Z" A. r- i, F5 y9 V y# F
// 譬如要对光驱实现禁用,可以这样调用此函数7 q0 y! l0 L, k2 J
// ControlDisk(0, 1);
& J/ C) z- B% c- J' a3 iBOOL ControlDisk(int nStatus, int nIndex)
! k: X( l+ c$ Y" ~4 \4 A9 S{
) c+ _7 {& V; p8 W# gif (-1 == nStatus)
. A& S# L v8 L2 T4 P{
: \) L. Q* @2 H7 ^, h return FALSE;
0 Y+ u. I; B/ H7 I& e1 F}
! {- g9 y4 B6 a
* F4 l1 ^ S) z+ \+ a v9 ]" l- nLPTSTR lpszMsg = NULL;2 v; z- M- s6 _$ _
try; t0 @( a. f8 i
{
2 b0 ?: X8 X5 ^ TCHAR * GUIDString = NULL;
: C$ D" X: c2 ] GUID guid;0 ]5 ?4 `5 D7 I. y% ^% c
ZeroMemory(&guid, sizeof(GUID));
% G0 W" Q1 M8 Y9 {7 | switch(nIndex)
- X- N' p/ \2 f1 \: H* M {
n8 M) @$ h9 S; d. ]; T. z8 x case 0: // 0 代表软驱: o/ P' y+ f- B9 f! \, Z& }
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
3 ]9 d& Z) @* E$ e' M UuidFromString((unsigned char *)GUIDString, &guid);; Q7 y5 m, K6 I/ i
break; 9 Q$ Q2 |! r; R* b
case 1: // 1 代表光驱
7 Q) V% f7 _" d GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
4 H1 h% a3 S3 R7 O6 e: ^7 A UuidFromString((unsigned char *)GUIDString, &guid);1 h" `3 P& w2 \* ]7 O% l5 ^8 ]
break;+ f+ ~) N9 `% u) e
case 2: // 2 代表USB
$ n; {! g2 K, E GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");! z4 j1 u. T3 ~- |7 J* f/ @
UuidFromString((unsigned char *)GUIDString, &guid);1 f4 |5 g' d8 P
break;8 S( q1 X' L2 R# p0 d
}2 j- [) I/ D4 }8 e7 O9 q
" u( J- Y1 c8 S1 F
hDevInfo = SetupDiGetClassDevs(&guid,; y0 ^7 H" e$ F; T, Q) z5 Q& L T
NULL,
$ n) H, k+ |, ?+ R- K) G, D4 O NULL,+ c: d2 g4 U3 `+ }. i
DIGCF_PRESENT);) I7 k7 _ n/ w. H0 q* \
if (INVALID_HANDLE_VALUE == hDevInfo)
1 O5 ~9 S6 P8 v {
. l8 {( u5 O; ?% \8 U3 } FormatMSG(GetLastError(), &lpszMsg);
1 ]7 q( d" g1 A throw lpszMsg;
. n' E n% R# M, P4 b; f! Z) M }! o% { Y4 z# a3 ~6 @" X3 F/ P
# e1 B) {. ] K5 y$ H DWORD i;
7 Y/ j& e! P2 Z: m9 E* q5 B. b SP_DEVINFO_DATA DeviceInfoData;
# R9 Y* h/ @2 ?; v$ `* B7 R0 C( o ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
( S5 f% u9 Q+ z" @ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);; b& l/ m0 E8 Y* o" r
0 @+ ~7 E# j% v* Z
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
- d w& J) E: }, ?2 s* R {
9 G8 L1 @* w7 b4 c, ~ if (1 == nStatus)
3 d j; Z1 L b) `5 A5 ? {
# Q' n' m6 f3 l StateChange(DICS_ENABLE, i, hDevInfo);1 V( u s1 r0 W8 R8 E) _
}
. ~/ @4 ?. @( q6 S. k* ] else if (0 == nStatus)
2 v/ r9 [/ j1 ?6 ~ F* f {! @0 {4 ~5 z! N4 J7 w9 q
StateChange(DICS_DISABLE, i, hDevInfo);
, |) d3 p8 G! o0 u. L& v- g9 b } # R$ w, \0 K1 x0 C5 P9 t b9 {
}" K2 L. F! t9 g8 @4 `: ?
1 E( F& x0 o: G$ }1 J
// 释放 device information set& C7 `' a+ m' ^( p
return SetupDiDestroyDeviceInfoList(hDevInfo);
8 j. y) U1 f" Q7 d8 R}
( _* s; U9 `7 s5 M5 Jcatch (TCHAR * pszError)
$ d. o6 L4 B+ m. n' x/ X) Q- b{
, \" W5 _7 c3 B+ h0 o' M+ { ::MessageBox(NULL,4 x6 t6 ?/ u3 f7 f, C% y) a
pszError,
4 q' S2 C% j: ?8 a- o" x _T("提示"),: _$ Z+ X6 t- N* B; ^
MB_OK);
+ m: n2 B- d; U6 q: v if (NULL != lpszMsg)
4 b: g" ]) D! g! p/ o {
7 t V3 O. j8 f- c; e4 Q0 i2 ^ LocalFree((HLOCAL)lpszMsg);: C' {+ w$ b) ]7 u
}
6 M5 ~5 b5 s" x. W9 g, X return FALSE;- d0 {/ H4 [* W8 j! L1 o5 b
}( @3 }# [/ V5 _0 W! ]. _& `
return FALSE;3 W4 K8 p9 f# p7 P( A
}
9 n! C% R1 ~7 }9 v. P' ^/ M" M: J" v. n$ s5 k9 m" V2 w* {
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
9 f1 K6 ?/ C& p. T* U" I) \3 j; }- s 据我观察,在注册表的此项下下:
+ \) s, ~4 ~3 d HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
7 F5 N! y1 z# n 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
- b! n. K1 @1 \& u8 r/ q" {& B9 u {36FC9E60-C465-11CF-8056-444553540000}( W. a$ Z7 `" ~) q/ G- p
这个是CDROM的
9 n; j8 r& _6 H0 z {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
- s! [8 n3 g- f& {3 s这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|