|
(dlutyuanhongl发表于2005-3-15 23:14:04); X" V' I0 W8 F* B* A3 r) Q: k
5 D! T3 W" @1 I这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
6 m; \" `4 m2 [' Z7 R// 必要的头文件和要链接的LIB文件; |" P0 A+ r; A& W" T0 C' ~
#include <setupapi.h>8 B2 l$ V7 I: s8 d+ |2 L
#include <shlwapi.h>
, ^9 q2 u" O! ~- @: A0 ~- U#pragma comment(lib, "setupapi.lib")
' I8 T# ?' @1 M* ~0 [#pragma comment(lib, "shlwapi.lib")! D& o# {+ C7 N2 D- E/ h+ M) k
# j: h7 F' Y/ R; I0 E- @& j2 W
// device information set(我把它译为设备信息集)) y& S* ^0 s+ |! a- ` V
HDEVINFO hDevInfo = NULL;* b; {2 }# y; K0 ?4 X& U
: N# Z% R2 V9 ~// 出错信息
8 B( _* i2 t- k& _9 Z6 Xvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
' j5 ?' _# ?9 T, h1 u* d{ ) h/ [* ^* K$ o" Q# m
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
8 t# V* z9 s9 B) Z. M | FORMAT_MESSAGE_ALLOCATE_BUFFER,3 w0 q# a+ S! Y' h4 Z7 q$ t
NULL,
2 P9 m8 l) w+ t2 U8 S5 _ dwError,
2 I) b* B5 B1 V! n3 U MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
4 J8 V! p0 R! Z (LPTSTR)lpszMsg,) c3 |& r1 O; l
0,7 Z7 v" ]$ T( m. R' f1 a8 p/ }
NULL);; J5 i: C1 M u
* ], ^0 k. O2 G7 ^* M Gif (!bOk)
) |+ E; @0 h @% f- \{
; ]# I* r$ D; p; V HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),4 B. j7 M1 M% v, _0 X* X0 J
NULL,4 J# v, Q8 C. y* l9 H, S
DONT_RESOLVE_DLL_REFERENCES);
% I$ E# k1 M, A. T! F7 M if (NULL != hDll)
/ T$ y4 h" _ I T& I7 D8 D8 | {
" Q, n) V$ K9 B% Q) r" Y6 S7 e FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | ' o: U. G: L) `- G. B9 _0 X/ Y
FORMAT_MESSAGE_FROM_SYSTEM,
0 R. \# L! V' @( R hDll,. _7 q3 x2 I+ k+ S
dwError,/ t* \. z" H6 W
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),. P4 W5 z% E; r0 e& p) K0 t
(LPTSTR)lpszMsg,* v! @% f5 W; \3 k
0,
" l3 F8 c7 }, ?/ x7 a NULL);* X- ]% |1 p0 N8 s
FreeLibrary(hDll);
. U" H0 J) A l% ?% n }
4 D+ S+ s6 E4 R+ V- [+ B2 X}) t8 U+ y& R8 Y7 |. p% I! Y) P
}
: S2 v* X7 i3 {, j& z( |# H; I f' p7 ^7 O* b) F- ]' D: U
BOOL ChangeStatus(DWORD NewStatus, : v [ C1 t4 ?. U
DWORD SelectedItem, 9 V2 M8 G( h/ L; e; |$ W- `
HDEVINFO hDevInfo)4 {. g8 `, _1 g Y8 u
{
* m% W3 x- u% w+ JLPTSTR lpszMsg = NULL;( D ? C4 O! F- m. S# i
HCURSOR hCursor = NULL;$ q% d5 ^2 u; t
try- A1 u A7 J$ m( J. S* A5 R
{
A0 i- h/ i" v3 t! U5 E SP_PROPCHANGE_PARAMS PropChangeParams =
% L/ p1 O8 L/ R' k {sizeof(SP_CLASSINSTALL_HEADER)};
/ D6 p' {+ }, N3 i4 n9 i% v/ U: ] SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
- y5 k& S) {/ J) W+ K C# o! m3 }* t; b; U- J% P" l: m) A
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
! U0 V" o3 r9 h1 c0 i$ Z: V: x
+ d! h' h2 s: ~ a5 q y/ B // Get a handle to the Selected Item.
7 _& T7 b# V! J2 c if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
f. P$ l# j8 }9 c8 Y {* u: H6 F5 C; i7 w) |) C+ U6 \$ G
FormatMSG(GetLastError(), &lpszMsg);
# F& u7 V6 H2 B3 o* }; Z9 g/ j throw lpszMsg;
: V+ z5 R, F) ^# B/ i$ P5 K" F }
) L3 S; H+ F4 I4 i2 d% \4 V# `: Y8 F4 d% c/ B$ P% l6 k0 z
// Set the PropChangeParams structure., O; p Y1 G$ L6 @- @" Y& }
PropChangeParams.ClassInstallHeader.InstallFunction =
4 X2 r0 Q5 `3 C DIF_PROPERTYCHANGE;( m6 P6 e9 r3 J7 c
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
# q% L7 H: B" U$ l PropChangeParams.StateChange = NewStatus;
8 A9 w) p& L/ \& |' t f; n7 A* u+ s( k1 }: ]
if (!SetupDiSetClassInstallParams(hDevInfo,& V) B3 l; Q; f$ b6 y6 Y
&DeviceInfoData,
: b! h8 n. S" \* P9 \ (SP_CLASSINSTALL_HEADER *)& ropChangeParams,9 U( K# M- }% a
sizeof(PropChangeParams)))) i5 j* t. L" N/ J0 A( h1 W' \+ o
{
2 R8 c5 I) b5 _* V( o FormatMSG(GetLastError(), &lpszMsg);
" E% x I2 f% u throw lpszMsg;
( A: U+ `' H+ ?! z" g* b }; b1 \) w, c% A6 S9 N0 _: u8 C
' x. Q, F6 H) O) H) d3 c3 Q! _ // Call the ClassInstaller and perform the change.
$ d& t, w: Z' r' _8 ^' f if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
, m# p% Q0 T/ m7 x1 } hDevInfo,6 f1 ^; u. A3 y4 y6 D: N6 e4 z
&DeviceInfoData)); S5 [9 ]7 w1 H) w
{2 X2 M; V v' Q( b
FormatMSG(GetLastError(), &lpszMsg);6 {/ ?0 B! L; Q# h
throw lpszMsg;
# \+ s2 g5 E9 W! T }+ Y' N# w0 [) [) v1 `, @
$ Z X% b% _+ l3 j SetCursor(hCursor); ! B& {/ v4 y* D2 {
return TRUE;- q" V: d3 n4 a9 C5 i6 r( X# W
}
) ^3 G# u. e7 W2 A# Bcatch (TCHAR * pszError)/ p5 ?8 S0 E; w! ~
{" o) @- P: K' a% n e- g
SetCursor(hCursor);2 h- m9 Z# V, v' s
::MessageBox(NULL,
) I% U0 n, W# L& a" @" h. ` pszError,
' H7 s- L; n0 o) c& {) c _T("提示"),
& O) r: {" e/ I0 p5 P MB_OK);1 r1 p4 Y0 P+ h$ e4 Z
if (NULL != lpszMsg)# ^- |/ T, l. E7 g) g) i) k
{
% u- t8 J; u+ X: t" U3 e LocalFree((HLOCAL)lpszMsg);# s1 q$ {! `3 d% Y0 `8 j1 q/ A
} & D7 V7 h' O" D
return FALSE;
3 F& a2 U9 c, E& x+ M* I} ?, E5 i m7 Y
}% D& l$ }' ?" e; _% x
% x7 v2 n. [$ R- a! v; E" U Y// 这些设备的启用和禁用主要有此函数实现
& y$ c- K4 |$ {, U// 参数说明,nStatus 可取3个值,-1 :啥也不做
3 ~' X8 K: |) Q9 I. v5 K// 0 禁用设备,1启用设备。( z) n- M+ J" w% [. \2 O( a9 v! j! o
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
+ l( u# Y* ]5 @6 \( C* S// 也是可取3个值,0 代表软驱,1 代表光驱! ^3 I5 }7 j* {/ @- f4 n0 P% V. g: V
// 2 代表USB
# A8 c" S1 M6 E$ c8 g4 Z# ~// 譬如要对光驱实现禁用,可以这样调用此函数+ D7 V4 R U9 m8 ^" R
// ControlDisk(0, 1);4 ^ H9 F |' z! Y- @
BOOL ControlDisk(int nStatus, int nIndex)
$ v( O) D. u, Z) h$ K" M{
: q7 y I. ?4 zif (-1 == nStatus)$ f0 ^# `* r# n
{
& b+ R8 ]9 J' l! i! N i3 e3 r1 j return FALSE;
8 q0 f/ i) z, ?" R}
; w. K/ E* u7 s& q. I$ A9 f ?, p, }" p; D* Q4 f! f7 N2 ` [% g) A
LPTSTR lpszMsg = NULL;
6 o) Y6 S" J% Q. p( U$ {5 rtry
0 C6 j3 D0 e5 K{5 Q6 g( N& m/ X* j2 e3 p* |
TCHAR * GUIDString = NULL;9 p. D" P* ^, T) c& q8 a
GUID guid;( t0 b; ?8 L. N' G/ a" C2 c
ZeroMemory(&guid, sizeof(GUID));
# m; L; V, P6 q% x switch(nIndex)) L: t( }) _* x
{
( y2 V' H' ]" e" w) l2 b; j case 0: // 0 代表软驱- M, G1 O' b F# W
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
3 J! z$ G# @4 `$ S5 |6 i% c UuidFromString((unsigned char *)GUIDString, &guid);
' g: ^# d3 k7 c8 Q4 b/ Q2 t+ W, O% k break;
2 A/ c& P) g( ^6 c) Y) T9 ? case 1: // 1 代表光驱 ^7 J9 o7 @4 s- Y" b+ R _6 z
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");6 a1 g0 W+ \8 b" ^' D" ^# ]/ r9 F
UuidFromString((unsigned char *)GUIDString, &guid);
. a" M* ~0 p, j& l9 T& |$ V" l break;" [& m) C$ t8 I N
case 2: // 2 代表USB ?0 m; @ R9 C+ k i
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
4 b; y E7 Q4 q* D& n4 g U UuidFromString((unsigned char *)GUIDString, &guid);
* u6 k' P; o: c5 V+ f3 h& U break;. X5 j1 U: t9 F- b- e
}" K0 P) p$ W0 s7 S" v3 h" c
3 l4 u: b9 ]) ^7 O/ ~ hDevInfo = SetupDiGetClassDevs(&guid," x$ f I) r2 c
NULL,4 I$ G& [5 _# W; M
NULL,4 U3 d7 V B+ Z/ x$ \( f
DIGCF_PRESENT);2 Y# ?: M$ u1 C0 K4 i. |
if (INVALID_HANDLE_VALUE == hDevInfo)- g" t; s$ ^; n' Y
{
7 M5 u1 J5 K2 j( m FormatMSG(GetLastError(), &lpszMsg);
; x7 L6 C( S8 K$ U throw lpszMsg;6 n" Y6 k+ F, J8 b* ~- Q+ H
}
) f; ^) }6 R* A/ q8 x! a7 [/ O2 o! ~4 m( d h5 Q
DWORD i;+ h+ g* e& Z6 \; A. q: k) K
SP_DEVINFO_DATA DeviceInfoData;
) e) O! Z) a ?* i! v ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
4 p5 T4 }( M1 e0 v% d; w DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
( Q0 ?: h0 U" \& p7 ?' u* P* k, F9 ]9 _; h; r# D
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)- ]4 D7 o& c* a2 q
{
9 \1 \' T! L0 a8 Z! Q) J if (1 == nStatus)
8 P9 q; u7 i6 X5 y+ _) C% [ S {4 [9 {3 T, q( y) A: q
StateChange(DICS_ENABLE, i, hDevInfo);0 A- X7 c( O! o4 v
}
, T- R- O3 X! S: G2 i else if (0 == nStatus)
) S% }* A' Z6 R5 ]. D {
) y+ R3 `% c4 u6 _; M& O- ^# [( w. z StateChange(DICS_DISABLE, i, hDevInfo);
6 V' f _! t) Z! D2 ~ }
5 T; G; R/ D/ H1 b# ?5 ?4 _ }
" F1 t* _$ I# \; a; t7 L5 S5 A, x& K M9 [
// 释放 device information set
7 {' b* z, s% j7 _8 `! Q9 W$ @ return SetupDiDestroyDeviceInfoList(hDevInfo);
% @5 s; ~, y# J/ r9 U" p9 f+ c8 P}( R+ K2 J3 H2 W" O7 S4 x7 R
catch (TCHAR * pszError)2 T, d! p( l1 a. Y, y M
{$ r& Y( N; V, C8 ~$ e* \
::MessageBox(NULL,* a$ J- u6 `6 v9 B
pszError," T0 C6 o- @: J1 G, K* }
_T("提示"),
! W0 @: m9 o6 F4 ~ R/ l MB_OK);
, ^, `1 s) @' e6 |- b& c6 X8 q if (NULL != lpszMsg)9 `4 H# }& ~6 y# r' k
{
: p: e, r: b; S/ e9 \ z E Z LocalFree((HLOCAL)lpszMsg);( s) S! r3 C1 C7 ]
}
. C( N' D ]% [, j5 L! S) l return FALSE;# |5 M- O4 L- [ B! \! W, m
}
4 o) [: L" O. v# U% jreturn FALSE;
. v" f2 \8 ]9 G# `0 X}
0 y2 O k( [4 r4 I, r
7 ^1 K i: H9 x: B 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
) s5 n, C1 H: [ 据我观察,在注册表的此项下下:4 B x' q; N4 l! \) ~
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
9 H' t5 f' t6 V5 P" W' ` 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
0 C# L; z( q E. r7 M+ p4 r4 h$ H/ ? {36FC9E60-C465-11CF-8056-444553540000}. |7 ]4 y0 J# j! ?. n) \
这个是CDROM的5 E5 w: {. E! N( W) ?* R P
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。2 g @% S+ G3 ]3 ]0 t& w8 n4 Z
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|