|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)& O& w/ v+ H& t4 y- Q$ J$ p
( p( c6 R7 i% @ |6 ~) v这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
, v! |) L$ z; a9 P// 必要的头文件和要链接的LIB文件
3 t+ V# m$ y; S0 t* p#include <setupapi.h>
# U% c( g! ~7 b, d6 l" \#include <shlwapi.h>
1 N& ]6 m4 j+ g# e( W ^#pragma comment(lib, "setupapi.lib")! w6 P9 j1 S: @+ i. F7 i: |; H: T
#pragma comment(lib, "shlwapi.lib")" @' Z. _" A2 t! Y6 q
3 y) G# y. ]6 R% s1 ~8 o) l// device information set(我把它译为设备信息集)8 v9 B; N) C7 V" h7 p. d
HDEVINFO hDevInfo = NULL;. R# E- C. D, R6 \8 N
1 D) r4 R' c8 X- I' {# {8 z1 {
// 出错信息% Y \! A) }+ [3 ?( Z2 l0 _' g" o: x6 I
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
1 o7 C& B! Z# z$ {6 [5 I+ G# H8 F{ 1 W. ~, j0 h2 u- @! R- B
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
' q$ u4 ?6 A) E+ G- n | FORMAT_MESSAGE_ALLOCATE_BUFFER,
) `$ t5 @3 W: b* @0 g NULL,
5 d- E( r5 g) j6 z% g+ p dwError,/ T+ n4 H, y# ?- c: v' O9 S' T
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
( \! R/ p6 R; Q7 T (LPTSTR)lpszMsg,# ?7 q% _/ X0 M6 \7 |
0,
. }8 @# ]( t5 b) B I% f% @6 d NULL);; P3 E4 y3 j* G
0 m0 E# d2 g! {" K2 x% \; B
if (!bOk): A! A; ~1 `* f
{
, D# [; `" A+ N7 w# ]! |* [ HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),6 h0 k4 C9 ~" `; K. ^
NULL,: i& s) V4 T$ t7 T- C3 O" f8 q
DONT_RESOLVE_DLL_REFERENCES);4 A9 j/ t) X3 \ e* {' w( d
if (NULL != hDll)
3 t) M' q; S6 _ {
, F. j* \0 u7 H+ W1 K FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | ' n8 ^# k6 X/ W2 z' D! N
FORMAT_MESSAGE_FROM_SYSTEM,* W b4 }8 @, Q* O+ Z3 k- ^- q
hDll,
! {! C9 Y1 o. `* q/ R, i9 t dwError,% r& s1 \# p( E9 s7 [" S
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),. Y7 a; G2 T$ r6 F' ]
(LPTSTR)lpszMsg,
7 J& ~9 e$ D9 E 0,- g; p5 t) S9 z4 Q
NULL);
, f" c( i' Y0 [; K) J% O! I) v FreeLibrary(hDll);2 S# `8 K' ^0 J! `4 I" m+ ^8 T
}9 h- C3 C5 ?3 }* e" S/ x/ G
}
( W2 u2 x, F7 P. d* o% z! n}
% E( e# j9 t& k" d. y$ X/ ]
6 v+ ~, F3 z5 M4 p8 Z/ K8 |- ]BOOL ChangeStatus(DWORD NewStatus, 4 G' Q% O0 Y" R% ~2 V4 l. m0 \
DWORD SelectedItem,
( I# p- y5 t( O+ G HDEVINFO hDevInfo)
9 X1 e* X ]2 @7 y" q) y{
7 T/ c) f5 s1 W' sLPTSTR lpszMsg = NULL;8 X9 @2 [5 {8 n& f u+ c3 K: D
HCURSOR hCursor = NULL;' o1 l6 a4 z5 u6 P
try0 @$ S6 {5 D/ p, F
{ H+ f% }+ w' X0 S: n) E
SP_PROPCHANGE_PARAMS PropChangeParams =
, ~) ~ b4 z h2 n. S- h6 @ {sizeof(SP_CLASSINSTALL_HEADER)};+ V5 d* [ s/ \9 \+ x
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
8 D5 X1 G; d" q5 v. @/ x" ?9 k" C' V/ m) L* ^! G2 C
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
& v. M7 y' c4 e! b4 Z& v% P" ~3 T- P/ `( J7 ]
// Get a handle to the Selected Item., X# ^9 Q- y: ^3 m
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))1 f# a3 O9 N, ^6 l% r5 m' \
{# M* j2 j8 Y1 \' z3 b3 y# a
FormatMSG(GetLastError(), &lpszMsg);
( \8 P9 m' l1 c6 ~ throw lpszMsg;9 m1 t y" }' \
}. ?- P. |% X: |
; c( J. J& j$ x1 X // Set the PropChangeParams structure.
h# k! ^4 F f) u0 X# D PropChangeParams.ClassInstallHeader.InstallFunction = ) }( P3 @& y- }( ~$ K- I
DIF_PROPERTYCHANGE;; f7 ^4 }' Y+ a6 A1 l
PropChangeParams.Scope = DICS_FLAG_GLOBAL;( E+ i6 O# u6 s8 T! |* g
PropChangeParams.StateChange = NewStatus;- d8 j5 Y$ Q5 N+ Y* B* R1 Z
2 l5 _$ G6 E- A if (!SetupDiSetClassInstallParams(hDevInfo,- N$ i/ w% ]! r4 U
&DeviceInfoData,
! O4 f5 v& u4 P8 v8 U (SP_CLASSINSTALL_HEADER *)& ropChangeParams,* P" S( m8 l- V: k0 ]& u$ m
sizeof(PropChangeParams)))' w8 P2 V q* ^* |4 d. x3 O! L
{ k0 h' Q# T5 c0 z. q2 R
FormatMSG(GetLastError(), &lpszMsg);# m0 a( Y* V, W' D) C( ~
throw lpszMsg;
! Z! r# q1 ^7 L! a9 K$ v5 ?# L }7 R; F3 N* ?) P5 V9 D# t7 t/ Q
3 t" \" A( f7 Z5 x
// Call the ClassInstaller and perform the change.
1 A8 h) e+ y0 I X: r% V- X. z: ~ if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,# V8 v7 t4 G7 C
hDevInfo,
' n7 B) |9 r0 x) A+ b &DeviceInfoData))' V3 N7 B, @' R
{; p% z% q" Q9 l( ]# R; F
FormatMSG(GetLastError(), &lpszMsg);
; T; Z) J7 h# h0 h( E throw lpszMsg;
% {' z7 k, H- w: D9 H" O }
# N1 K @# o1 c7 e8 V3 k- P0 L3 i* c' U" U. j
SetCursor(hCursor);
1 I% A" \. @2 X; g, I) @) s return TRUE;
$ U- \8 q9 o, n}4 e: \* F: u8 W
catch (TCHAR * pszError)
, E7 j+ p! U2 J{% y g3 |, ?; h$ `* }0 r* l
SetCursor(hCursor);
& a6 A9 k/ i1 H G) c4 _4 [ ::MessageBox(NULL,2 r1 O; o% _# r& ~2 u. ?
pszError,
* r) i( z9 U5 s: O) _ _T("提示"),& i* _2 A: Y) g# u! L4 _: V% H
MB_OK);1 ]+ y; p7 p* K$ c# J+ j, x% g
if (NULL != lpszMsg)
# s7 b. l5 t& B7 y; T: k9 x, _ {/ x" i& B) V, { |0 m9 |
LocalFree((HLOCAL)lpszMsg);, f F& F& Z& z) {% F2 J" F0 P
}
/ r& G+ _ Z3 s( r; p# m0 S return FALSE;6 j! E8 d9 B) ~7 a# Z$ Q
}
3 t9 [8 w- k- a/ j4 F6 c}
$ f' O! ~% x& n0 _& H7 L
3 e0 V2 F3 Z9 R1 _, R// 这些设备的启用和禁用主要有此函数实现
; h9 a5 m% ?- g; i7 o- z" ]4 x6 t// 参数说明,nStatus 可取3个值,-1 :啥也不做+ s( Y, P7 o( L2 J) l `
// 0 禁用设备,1启用设备。' R5 ^! i% d' z4 u
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用3 A+ f. ]1 R3 Q8 A$ g5 B
// 也是可取3个值,0 代表软驱,1 代表光驱
+ ^8 C! P: T2 M% g3 {; y( O// 2 代表USB
4 i' V( `" }( Y2 l: ^: w0 z0 s// 譬如要对光驱实现禁用,可以这样调用此函数0 \7 `$ u' p% Y1 I' |6 s1 s9 B
// ControlDisk(0, 1);. y$ U2 x% O: _
BOOL ControlDisk(int nStatus, int nIndex)7 s U r8 V6 A/ D# O O+ z% p; o8 K' n
{4 y$ Z" z6 n; U0 b: g9 F* y
if (-1 == nStatus)
% h; p4 a& _9 P6 f1 H1 ]% E$ M{
$ ~ r1 l, H$ S) Z, {5 }6 h8 [) N return FALSE;5 Z! j8 G; v$ s1 U5 k% H4 J! c
}
2 h0 x5 a& g' _. a% g
0 B8 M1 z/ T/ X0 tLPTSTR lpszMsg = NULL;0 s* ~. Y) V4 n* J( D
try- u( B, ^! I: S
{
' r4 \* b* _4 _2 [& r6 m b$ K% \ TCHAR * GUIDString = NULL;: ^% [$ K' F( F: T& Z2 ~
GUID guid; z8 d8 v3 E/ }3 V }
ZeroMemory(&guid, sizeof(GUID));) S5 [0 C9 a- v- v
switch(nIndex)4 K& \1 U/ d6 l2 a* ?
{. D M- S0 R7 b; Y' t) g" F+ x
case 0: // 0 代表软驱. K4 L8 D0 |0 q6 B9 X
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
5 }3 v- M R# {+ h. y* L/ v UuidFromString((unsigned char *)GUIDString, &guid);
j! [6 e/ o/ N" v break; " b \! c* k, m2 q) F) h
case 1: // 1 代表光驱 8 U$ ^1 b( x& Q2 s
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
T3 i ^; @. I! h% E5 O. M6 d; y UuidFromString((unsigned char *)GUIDString, &guid); l6 F% R; n& c! F( h5 n) @
break;
; w4 Z6 P" E$ l- q case 2: // 2 代表USB6 Y6 ^* ?8 U" J/ u- u( w
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");6 l; M, a3 O% ~9 g0 Z
UuidFromString((unsigned char *)GUIDString, &guid);
! r8 [3 e$ Y6 B& _: Y; b8 D2 | break;
' R. ]3 F& l+ X: L7 B& D }# [! w: G( k7 e5 {0 Z3 ~8 M
( A8 g) b# o( V/ U! l
hDevInfo = SetupDiGetClassDevs(&guid,1 W. N) [) K* U* W1 f; y; V) }, R
NULL,, s6 y9 v( q G* g/ _( r: a
NULL,$ O- }. p7 V/ @0 Z
DIGCF_PRESENT);' m$ }+ ^# u; P1 ], E9 _" N
if (INVALID_HANDLE_VALUE == hDevInfo)
2 O6 L) V* e0 ^1 e, l { x& P2 v; R. p
FormatMSG(GetLastError(), &lpszMsg);! a+ G1 V6 }0 p6 I
throw lpszMsg;
1 b; D* f- f2 n# J' V; U8 U# C/ g }2 I. v: M6 _) o/ E2 C; s' _5 [
k4 C2 {0 ~; A; h6 i2 Z DWORD i;
6 i0 P+ w4 f1 Z! r SP_DEVINFO_DATA DeviceInfoData;0 |* G0 \$ {% j5 ]/ M9 J
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
6 X0 ?1 T) L# Z7 V4 ~+ c5 I DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
h1 d* C ^: L1 s2 Z4 V8 V/ |- g. ~/ `
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)- Z; m5 ?; D* U3 Y. H% b
{: o& W! }( i8 ]4 T1 z$ K. y% h" G
if (1 == nStatus)- @6 t( E+ m2 [ v- U
{7 H! _2 T6 d% j5 I9 L3 a
StateChange(DICS_ENABLE, i, hDevInfo);# g% R" s, S6 U; Y
}
) \( U$ \# w4 n3 {, r else if (0 == nStatus)
; H6 h& V3 ^3 ?! o# O5 C {
8 j8 m7 J2 N) Y8 k& |: Y% ~+ q StateChange(DICS_DISABLE, i, hDevInfo); m' R$ e) r: U6 L0 s
} ( q# w0 B7 I8 `" D2 s0 b/ U6 ]- [2 r
}
6 K% b7 W* g7 A0 G! Y& a% B/ j& J' v( E
// 释放 device information set
/ o. j. j3 s6 a2 _9 A% J return SetupDiDestroyDeviceInfoList(hDevInfo);& I7 E* S d2 w* w# l0 W: c. F
}; y% M) f$ `7 I
catch (TCHAR * pszError)
) I3 n6 t, w- F V{
4 K# p: Z7 [+ x: J7 A0 g( @ ::MessageBox(NULL,
0 x. R3 e% d: ^$ C8 |+ z pszError,
6 ^2 [ N+ T3 d z) N _T("提示"),! J1 P2 b: Y$ J- F C i' X
MB_OK);
+ G- R( M. K/ R) I, {5 v+ } if (NULL != lpszMsg)9 K* P4 |- m: e- k( w
{$ C: Q! k$ E* _# o: }5 T
LocalFree((HLOCAL)lpszMsg);
! [$ q0 _# y* x5 R$ M; G7 N7 l }
& _% b/ f7 w. [% h return FALSE;0 F! q" J+ z( x% t
}
8 ^ u0 ` v- |+ ^/ Y- |return FALSE;
1 g! ?) [9 u u1 Y! X! N5 |}/ {4 g! k+ O/ G4 I+ z* ^+ i
5 E+ p i1 [9 j* ?1 ?8 e
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
$ d# H. @& ]2 _( _7 o 据我观察,在注册表的此项下下:4 P( q: R S7 c6 |, @# S
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\( v- _# ` M# F |; \
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
# p# A' T( X" a; U- ?) S7 A {36FC9E60-C465-11CF-8056-444553540000}$ H1 N; [) ]) S n; ^' ^
这个是CDROM的
5 ?" F: j! d+ @5 _7 g/ V1 w( T0 L! O {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
% f$ ~( W+ _) N' O. _7 F5 q% B这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|