|
(dlutyuanhongl发表于2005-3-15 23:14:04)' r1 D( V: w) `& m0 L# Q7 ?8 F
; G: Y, W& ~* j$ e3 Y. O; \( @; V
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:) y; Q' y8 J( f& ~% ]. x( z# n3 m( m, Y
// 必要的头文件和要链接的LIB文件. W# s/ ?1 h# U; O
#include <setupapi.h>
. y( Z' [, B: u% r R/ y#include <shlwapi.h>, I+ i; S! i6 P0 m
#pragma comment(lib, "setupapi.lib")5 V5 h* U' f4 z- k" u! M
#pragma comment(lib, "shlwapi.lib")
- p. k, e. @6 N& P
; i0 {) c; R# F// device information set(我把它译为设备信息集)9 }$ J4 Y) h& A0 u" M
HDEVINFO hDevInfo = NULL;
! ^) g! p" w1 \5 N; R0 E, v$ _
5 c( d; s/ n+ o// 出错信息0 W4 o ?6 f$ d5 C
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg). F. B) ?7 {, ?! g
{ 4 r* n5 _5 v+ i2 W( e
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ R7 v* a9 K0 l. c | FORMAT_MESSAGE_ALLOCATE_BUFFER,3 q- M8 Y( R4 n, n) S# K
NULL,. n2 X) y0 M" R. ]) D8 p# Z- t" c# A
dwError,
( a- G6 D; M/ e4 q$ o$ k6 y MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), c- i2 l2 w, ?% T' W# M
(LPTSTR)lpszMsg,
6 z0 B, C& g8 P' {7 g% p3 ] 0, \7 g" C. y" T9 K" b2 x" l
NULL);7 n; l; P/ U. U
: w; j( W" @, n* ^, _ i1 D
if (!bOk)6 A. e* D$ l% l8 F& |
{! A/ k. v+ N6 L% U% D1 c
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
$ N; P6 e C* o5 s3 W% U- c8 I9 J NULL,
: Y6 l; _# T% K F DONT_RESOLVE_DLL_REFERENCES);
, g! M) R6 R; N1 A5 ^ if (NULL != hDll)
: k3 [5 O. i. v {
. V/ z9 G. a+ k8 L4 u# L FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
3 a- X0 q$ z6 P$ H$ |: m" \4 z; j FORMAT_MESSAGE_FROM_SYSTEM,
3 b9 W, L; I" k/ R5 g0 H. X' U& N hDll,
# k# e( C( [2 |2 O, c0 y4 V dwError,# m/ W, U( A7 ~3 Z0 I
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
0 m1 w" i( q$ k9 h5 ?0 G" |7 I (LPTSTR)lpszMsg," a' C6 e+ ~ J- Z
0,
% ?3 x4 c1 U; s6 k NULL);1 _1 w) H; b9 m1 M/ ~
FreeLibrary(hDll);
' k) ^: Z( `' ?8 @7 A }
, {" j9 {! H; ~: T4 o' d. e}
( j3 O$ o) ^" E2 q9 B}
2 M- s9 M$ z/ Z/ i; c
7 Z% q/ b- k4 o: \* sBOOL ChangeStatus(DWORD NewStatus, % P, `# o k% j$ Z- |
DWORD SelectedItem, 7 Y1 X+ O6 a+ k. g
HDEVINFO hDevInfo)
7 B& d* Y9 v: h1 Q{
9 m/ @: b P5 F% R' ZLPTSTR lpszMsg = NULL;8 [/ o6 o# V* R! Q+ e- t
HCURSOR hCursor = NULL;- O; j4 q+ w! P
try6 R2 x1 U8 w; @6 {/ D
{
# ~5 X7 T1 q% S! F a" Y2 y SP_PROPCHANGE_PARAMS PropChangeParams =
8 t9 {; `/ J7 q0 C" H T; w. U" L {sizeof(SP_CLASSINSTALL_HEADER)};( k% x! }6 X, T8 K" V1 k
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; ( S2 J. f8 K. z: z
: \. g7 c) g" a: x* V8 _
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
5 ?8 x" f9 F4 S/ q T! v2 Q4 W8 K( W- e! [: o v7 I7 B
// Get a handle to the Selected Item.
* m1 _' k7 \6 G8 b( {. x if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))3 ?( Q0 d6 e" n: c
{# H; b9 T4 |8 i2 b
FormatMSG(GetLastError(), &lpszMsg);; @& n$ ~6 I7 ?; E7 ^6 u* ^" U- g
throw lpszMsg;
* D: ^, W0 q3 J4 i7 J }
" S. ?" H. }/ F; E3 t/ ^0 @1 y- d3 L0 ]; w& o) n: Z, N! B
// Set the PropChangeParams structure.
* [9 p) m+ D3 d, I! b2 b8 g/ R PropChangeParams.ClassInstallHeader.InstallFunction =
( q8 ^! d3 e* u8 w' i; H" ~: m/ V DIF_PROPERTYCHANGE;
6 I* J. r2 ^7 P' Q PropChangeParams.Scope = DICS_FLAG_GLOBAL;
* E2 Y1 t6 U0 N PropChangeParams.StateChange = NewStatus;+ l9 Q/ T7 Y; G+ h3 o
7 E) s( l" h' \" F; p7 D. }* {1 @ if (!SetupDiSetClassInstallParams(hDevInfo,
7 a1 E$ u5 Q. ~0 c) w/ y &DeviceInfoData,
, Y2 h4 m6 W& U# N/ Z4 P* } (SP_CLASSINSTALL_HEADER *)& ropChangeParams,! P0 F0 z- a! d: Y0 B' F9 o
sizeof(PropChangeParams)))
$ S! f; P! W. S8 F* d4 V; p {& s8 V2 w, }4 H& a& F/ o" } P! s
FormatMSG(GetLastError(), &lpszMsg);$ n; K- B ~* A u
throw lpszMsg;/ Z1 R( A" U. h! g/ f! j
}
+ m, F, } ^& C0 I b) a; d% ? o/ l/ s: [5 p9 Q! i6 c2 h
// Call the ClassInstaller and perform the change.: x9 C, w" P! @/ {0 ^0 ]" n1 T; ]5 \" N
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,& k# Z W7 M( _% x8 z% M9 W2 x
hDevInfo,7 _7 S; }! B. a/ W7 [
&DeviceInfoData))
: A" f3 k9 A1 n% W; o {( U5 T" J/ `; i4 _2 w
FormatMSG(GetLastError(), &lpszMsg);
+ o; p1 H& N0 I6 T- N0 W \" [4 h throw lpszMsg;
" q, c4 w N% A. R* p. C! F/ Q7 G }: Y# g# D8 ~" Y
4 |( b' z7 H8 n. V% q+ U
SetCursor(hCursor); ( a2 K& n1 G% d& ?* k& x
return TRUE;
& ? E- r. E: X- K+ N" \: q}
. w8 d( N) \. F' v" X; P/ x( Rcatch (TCHAR * pszError)
6 I) U' l5 [8 R& k: _5 f6 u{
* j1 D1 s# r( D$ l+ j SetCursor(hCursor);$ M# O1 \5 t; l$ a1 s: A
::MessageBox(NULL," q7 }8 B( s# ?( f/ C" t' A
pszError,- T! D3 [; N: Z5 A+ A
_T("提示"),
# D/ P# m2 p; ]2 j6 e4 g MB_OK);: k. y# G1 f7 `4 M: K% X5 V& `
if (NULL != lpszMsg)
: R+ b: R. O6 ~% r2 ^ {
5 f& L- D1 z, H4 j8 W4 T$ ] LocalFree((HLOCAL)lpszMsg);' h: V+ _4 N! r0 J
}
d8 j$ H4 h5 S6 v$ I: U R return FALSE;
. \! f. ]7 l% \7 i( Q- \2 l6 m}
) ]7 }0 P2 t/ n& D# n/ P}
5 N9 F! [& ?" ]' N( ^7 {$ _4 Y% X/ n; U' q8 A* V) M
// 这些设备的启用和禁用主要有此函数实现
1 F8 k, M. S+ q2 B: ?4 b// 参数说明,nStatus 可取3个值,-1 :啥也不做
; m$ A( |8 n% `" u6 i1 j// 0 禁用设备,1启用设备。
4 D; @5 B6 h! B1 \// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
) k! r3 q' G5 H2 w; w" c// 也是可取3个值,0 代表软驱,1 代表光驱/ r3 [! @" t! P! F
// 2 代表USB3 D5 k) ^! \. ]2 B% w
// 譬如要对光驱实现禁用,可以这样调用此函数
' p3 X3 D$ I* }* Y, O( o' ~7 W// ControlDisk(0, 1);
& u t& ^5 j9 `6 L2 Y* OBOOL ControlDisk(int nStatus, int nIndex)" k) d4 T* q. j8 P( F
{ z/ l. M/ n% a! X
if (-1 == nStatus)
5 z; T' b, s3 o2 H8 X{
+ H/ p, }! t0 b7 o1 N4 s% C return FALSE;
( y# R0 U% q- {+ V/ x9 W' |}
5 C* g! K* }* X, i6 ^& ?
5 i3 W' z/ m3 `( r N; XLPTSTR lpszMsg = NULL;' ]5 J. G& d. J7 }
try* e" `( L. U- i8 i* I
{
, S D" }+ K# x3 Y {. \1 b* r: k TCHAR * GUIDString = NULL;! @! r: }# v% N4 a; n
GUID guid;
7 g+ Z+ N) V! H: n+ E% k5 U ZeroMemory(&guid, sizeof(GUID));
5 J0 s T F: n switch(nIndex)
2 a4 |6 j9 J/ @" { {
) `9 v" U$ C# J E" \5 I case 0: // 0 代表软驱
# `4 X- A: p/ a9 K GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");5 W7 M+ I: D. D$ I0 T2 d" G. Q
UuidFromString((unsigned char *)GUIDString, &guid);& X/ M5 Q; O+ w0 B5 F* V: G
break; ! v9 M8 w* R* n5 I
case 1: // 1 代表光驱 ) _3 x# e' K+ X6 z
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
& L) ]1 V3 b) b7 x; V! |! ~- Q* ?9 o UuidFromString((unsigned char *)GUIDString, &guid);
% O$ s9 t+ b7 m# P$ J7 W" u' J break;2 k5 u5 V+ ~2 U- H; ?$ ]: M K7 s
case 2: // 2 代表USB
]: w: p5 J* ~6 y* Z GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");" A$ N, u+ y: {# ]+ ]! C$ o
UuidFromString((unsigned char *)GUIDString, &guid);3 M* t" p' s0 {: D7 v( w% c( N2 e: h
break;
- K( W! z# ~, |, x+ m; t }
+ S( ~/ D/ G Z* ~$ Z; w& M4 p7 N J# |8 r h* k
hDevInfo = SetupDiGetClassDevs(&guid,
& Z3 e h5 }" l- \) `2 q NULL,/ e2 P" y/ c8 F6 ^) y7 j! ~
NULL,
# s. R' h" m9 T8 F. a4 T DIGCF_PRESENT);9 j6 p$ q( G5 Y4 S$ B! @. C
if (INVALID_HANDLE_VALUE == hDevInfo)5 n7 N ^& i d/ E8 [/ @, g# L
{
0 c! V0 J6 e. E* T, z$ Q ? FormatMSG(GetLastError(), &lpszMsg);
9 z1 t4 F/ N3 d/ Q) |% F) H: X throw lpszMsg;' @$ T) K. i; e/ C, p% x4 c
}
& O% p8 g7 w* h" o. a& z9 I0 Z) F/ ?/ Y) p
DWORD i;
' L( T' x5 U6 r/ ^" |& t SP_DEVINFO_DATA DeviceInfoData;/ i1 ~ N [5 F) |
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));% }. Z8 g) p& J# U4 n7 |/ b
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);' J8 k1 ?! h; M: b3 W x
$ z4 X( j% m4 C# p0 ^; k4 Z
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
- Y6 \8 v& c% H0 G {: z4 [2 c9 n5 z, M6 S o
if (1 == nStatus)6 k0 x$ [2 t# R7 f9 t4 [6 o
{
+ w( r, @7 p( P2 C. K; } StateChange(DICS_ENABLE, i, hDevInfo);
5 p' U% X0 [: G) Z! r/ D }
( J: V4 ?1 R W- X) ~4 F else if (0 == nStatus)
8 R0 o8 e1 B* H1 j. H$ J {
+ l5 G) ^5 z$ p {% M- E/ T/ _ K StateChange(DICS_DISABLE, i, hDevInfo);0 {% f* `! G* R5 F, Y+ x& m
} - N( M& |. ^9 k5 ?+ |1 }
}; X* V% C3 s6 F
, i) e" Q: H$ p7 j: R. B5 z% q // 释放 device information set# V, S9 W8 L* I& Z2 p
return SetupDiDestroyDeviceInfoList(hDevInfo);
3 d/ h$ G+ Q& D) [' h* [# W8 ]8 V, e% M}
/ ]/ q% p1 h; G8 Zcatch (TCHAR * pszError)
8 B- @: f* X1 `9 J% a{
8 b- H% B4 U, z+ [4 L; m. h ::MessageBox(NULL,
8 i V2 M. \4 L2 P: A pszError,1 S8 a4 ]( z) d! t- o! e! b
_T("提示"),, ?& i" j4 Y1 g) z" V+ V
MB_OK);# Q1 a! |& j) y7 Z
if (NULL != lpszMsg)5 K" k4 Q' q" E% X* g$ U
{
! t& u4 y4 Z9 G4 l LocalFree((HLOCAL)lpszMsg);
" A: ~* V& y5 R, g! S/ _; F: F: S } ; N9 U9 W. S0 w+ L4 L
return FALSE;8 q/ t1 j+ r$ i2 |! D* B
}
# ]1 Q# y w2 H( h4 x3 Xreturn FALSE;7 }4 L/ y; V7 B# w7 x
}
" M4 ^# [8 d$ j1 f
) I. P- Z3 z/ E3 @7 j 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
" c" \% L4 f, @ 据我观察,在注册表的此项下下:7 i$ e' |' V" n! D* E& S/ W# u0 Y. ]
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
+ r" x; s' R8 Q1 x! z( _2 a* t 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
' ]4 \5 R1 _" P. W) v {36FC9E60-C465-11CF-8056-444553540000}* b' L! F$ Q0 M8 \' |
这个是CDROM的
+ R; ~/ i+ I7 |# Y {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
2 J1 @$ H7 v. k y1 c( _这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|