|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
' B, W$ ]3 @. m. h
6 K6 H, k5 C5 c! M' y2 g这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:. b- H3 w( `. a& [
// 必要的头文件和要链接的LIB文件
4 b2 t+ R2 L9 n6 b0 i: K v e( H6 {#include <setupapi.h>$ D3 g% S; q( _; G( S0 Y* J' i
#include <shlwapi.h>
4 N, J! E$ r- N" Z#pragma comment(lib, "setupapi.lib")) `4 \' n! k# J [8 ^
#pragma comment(lib, "shlwapi.lib")
, m: v7 v3 v8 y) k4 K# n0 ~
7 S% p! u( h- a9 [# C// device information set(我把它译为设备信息集)
) f* v' U! S% B3 k: ]7 M% eHDEVINFO hDevInfo = NULL; E9 N3 G" k" J: A" p2 S
+ \" j6 H& h$ e# u7 i: `/ D: ?// 出错信息+ x: `. |7 m+ _* Y2 X
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)$ J$ D D" J3 c% ]' d8 ~1 v
{ & s3 w+ m3 z. V5 n! `1 l% J
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM $ w% m7 j5 \/ c& o; P5 P7 h
| FORMAT_MESSAGE_ALLOCATE_BUFFER,. G! @& d& p: S$ s
NULL,# y$ G; a. w G4 J
dwError,
( _4 F) ~* N. }; M: Y* H2 o# x" D MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
$ q6 |& l3 O9 I5 J9 J; b" m& C# g (LPTSTR)lpszMsg,7 t# }, w9 A$ |$ L1 J8 \4 p
0,
6 T9 j) N9 ^' O NULL);% v- A% |5 j" M5 I; i( Z l1 g
0 K; w0 [5 y' k* X9 X
if (!bOk)
- A$ U6 `; ?5 Z{
/ r0 ^# ^! O% ] HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),% G B9 V, n& T+ E4 j& |7 |
NULL, w5 ~. q: q: O5 ^/ A- h. g
DONT_RESOLVE_DLL_REFERENCES);; c: h7 e# q% f: ?. C' F& P7 X
if (NULL != hDll); l2 U- S0 P! \1 H# ^) ?1 ^7 l
{) P2 Y4 Y9 x( q# [1 }5 b9 f0 p
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | 5 [( e, A+ i: D5 T( I3 I( r/ s
FORMAT_MESSAGE_FROM_SYSTEM,# x4 d- y" A5 n7 |4 C& c: h
hDll,/ G) [, y6 n5 j! K7 M
dwError,' b/ N& x% B' o/ Q# w4 M5 Z
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),! H+ K& W4 c5 \
(LPTSTR)lpszMsg,
: j+ f4 p& U" ]' _6 T& t 0,+ W4 c A) ? R0 c* e6 \
NULL);
8 l% U2 Y" X0 ~ z( Z; G FreeLibrary(hDll);( Z$ ?' i3 k. _
}
( o6 T/ K! ~2 L( O. F/ z+ O}
' A' Q9 F, {: k}3 j2 ~0 G1 T, h. ]
' H/ p1 ~8 \1 I8 g$ y
BOOL ChangeStatus(DWORD NewStatus,
& ?& V A) h! y7 G, A' l' ~4 M9 {) X DWORD SelectedItem, 1 N- g: ?: z) b3 @4 k: t" w: h
HDEVINFO hDevInfo)
; C- Q% ~5 d3 C. w3 l9 y1 [+ [{- a2 |# }7 J* S9 B7 l$ G
LPTSTR lpszMsg = NULL;3 ^9 k( c1 B/ j9 p) g8 p2 ~ u, M% y
HCURSOR hCursor = NULL;
( x, |9 L8 A( t5 ]try$ p8 X; C+ p9 c5 ^
{/ L% Y' e6 s2 `7 T$ B9 @7 w$ ^" d
SP_PROPCHANGE_PARAMS PropChangeParams =
* y) F/ N. l5 G: s t- ` {sizeof(SP_CLASSINSTALL_HEADER)};
8 z2 R3 Z+ h4 p0 G% w4 Q SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; ; ]0 [; H: Z3 O$ _) g2 H8 Y# T# {
]; l0 a; k9 O6 ]0 _$ `
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));2 v: ?7 H6 h! d, O& G
3 M' [9 ^7 E! U; G$ h
// Get a handle to the Selected Item.
2 F- D* b U1 R5 [. i4 B! m if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
z5 e0 @+ O0 h7 ] {
3 J; t, h, d% Z FormatMSG(GetLastError(), &lpszMsg);
0 ~) {+ [$ ^9 u throw lpszMsg;# e# S9 G: }( R- J
}
+ G: a2 i( L) M, ~; y7 Z% \, I6 h- H7 E, ^! w1 A/ g( @- W& _
// Set the PropChangeParams structure.
4 X% w" w% [" s, o+ M8 I' n5 _9 i PropChangeParams.ClassInstallHeader.InstallFunction = 2 r+ V7 g3 }; [" F* {) e
DIF_PROPERTYCHANGE;
: P$ ~1 {5 V/ R" X7 x- D7 Y PropChangeParams.Scope = DICS_FLAG_GLOBAL;7 X7 J7 t4 Y4 J9 R
PropChangeParams.StateChange = NewStatus;8 \% t6 i; t6 e# O0 q/ Q- @
5 O7 C6 A0 h: q2 I8 R# D if (!SetupDiSetClassInstallParams(hDevInfo,
. N/ V! M5 J) U. v &DeviceInfoData," L R0 Y" G& ~
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,% ^" y" ~+ ~2 c4 ?% c; I
sizeof(PropChangeParams)))4 h8 S5 Y, D. }4 y- b* E: C3 I
{
6 K n) n) b8 H FormatMSG(GetLastError(), &lpszMsg);
, R/ e k0 ]9 o throw lpszMsg;
0 b8 P) m2 K: ]' K4 N }: \9 s' e# ]2 t( f4 x$ E
' {8 u; K! W# u0 s- | // Call the ClassInstaller and perform the change.
5 d+ e$ `1 g j! Z& Y if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,$ H, J! @$ t* ^
hDevInfo,) |+ l' Y1 r+ g; V* D/ P
&DeviceInfoData))
* I9 Y; m0 q4 d' F {
/ q# V9 m+ l4 E8 O9 H2 h# r FormatMSG(GetLastError(), &lpszMsg);2 x4 ~: ^" `3 ?4 I, J4 f5 p) P
throw lpszMsg;
1 y9 S9 e* y6 [( @! ]! A6 y0 \ }4 ~( d5 M5 e$ \7 j" X0 ~5 r
) {- I3 u) W6 E* s: c
SetCursor(hCursor); " `! K1 P, F7 J: @
return TRUE;
# ]# A5 p& r" l/ T} ?7 d* ]$ r$ `3 M9 |% s* T
catch (TCHAR * pszError)
3 k- y0 D' `% S& }8 Z3 \{
1 g# _7 Z2 M: d& r9 `& }7 e SetCursor(hCursor);3 x5 o* h0 w5 V' K' x1 t( x
::MessageBox(NULL,+ }1 o' S5 ~7 } m0 C
pszError,
7 l, N/ ?& O! }' M0 y$ x9 @ _T("提示"),
3 {$ i! t$ e8 n* q* C+ @! H MB_OK);/ z9 u' R" F) e. ?% k4 R( p/ e6 ?. q$ P
if (NULL != lpszMsg)- e4 h+ N; B8 U0 q/ x# {
{
|. X+ s4 B, p5 s LocalFree((HLOCAL)lpszMsg);
+ K- m; v, y7 ?, K } 2 R1 Q( f. o8 C1 t; k, t
return FALSE;2 J# S i( |9 S$ P8 q* E, D! N
} 2 G; k6 Y2 d5 s, n8 V U9 x; H
}2 w. B4 b1 `" y; x* @
8 A4 ^6 T% l9 M0 M; W: w L// 这些设备的启用和禁用主要有此函数实现. X/ J1 x" v, f# n e n( a
// 参数说明,nStatus 可取3个值,-1 :啥也不做% \9 e" w- k1 b" h W
// 0 禁用设备,1启用设备。
! K3 ^: \% j4 P// nIndex用于控制是对光驱,软驱还是对USB启用或禁用7 C' E _' I/ V7 V- h/ [# t* e7 n
// 也是可取3个值,0 代表软驱,1 代表光驱
+ M6 R% W/ R7 ^/ l& l// 2 代表USB
1 l9 k- J. s' Q( G" t0 O// 譬如要对光驱实现禁用,可以这样调用此函数2 W/ B% s+ s: {! [% R3 w, [+ O: X
// ControlDisk(0, 1);
9 U+ d+ {( z# T3 C, ~: R8 l: PBOOL ControlDisk(int nStatus, int nIndex)
- g3 D. A2 ~( f8 N) Z; s4 g* {{1 G! i* p8 v" U3 X% Z9 D
if (-1 == nStatus)
+ o2 \5 Z0 s0 E, L# i{
; m: ~( n9 ~4 f' I$ \9 Q6 E return FALSE;
( p5 D6 b u3 {2 m}
9 U+ n# w E5 o
2 i) o" n6 U- U8 m2 jLPTSTR lpszMsg = NULL;$ u) M$ ~- w8 ^( l+ a
try
. a o& h+ a! {+ F. s8 E; ~8 z{; O6 { Y5 m4 q
TCHAR * GUIDString = NULL;
3 L# v3 K, f) L3 W g9 e( e4 z! v GUID guid;
, ~- s! l8 F; l7 h0 k$ X ZeroMemory(&guid, sizeof(GUID));- K6 T) x Q3 N8 F1 N
switch(nIndex)
1 r0 M0 N. e/ F5 P% ]! P" E/ K {* ?, o2 q {: i
case 0: // 0 代表软驱% O0 j: r! m8 e. s4 X9 n! j# Q6 l' z/ ~
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
w( Q% [: L1 a: s$ r* _, p- c6 {0 G UuidFromString((unsigned char *)GUIDString, &guid);
) g! z9 Z! m' o9 P% w break; 9 C) T1 @" K `2 o# X
case 1: // 1 代表光驱 4 j( H7 z/ R$ g7 R& o, N
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
6 _& n( }1 g6 A: k ? UuidFromString((unsigned char *)GUIDString, &guid);
5 F3 N& h7 w0 N break;& {6 S& ]2 c" ~$ X' [& {
case 2: // 2 代表USB# Z) R$ y5 W+ L/ w
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
3 T* X. y7 m/ C7 P3 h3 } UuidFromString((unsigned char *)GUIDString, &guid);
4 T6 B1 g) E e( c# P break; @ H0 d4 r! y. B. D" a" M/ ]8 g+ m
}! V M/ N- _. _( T! U9 q" w
. E, \& ^* Z8 f' W# [
hDevInfo = SetupDiGetClassDevs(&guid,
9 v8 U# S: b: H* Q: R& q NULL,6 I( X; x) T: J4 p7 |
NULL,
' |8 z4 M4 q7 Y5 \2 ` DIGCF_PRESENT);3 I# {( d# P$ \( c; l* B# m" g
if (INVALID_HANDLE_VALUE == hDevInfo)' R9 ~$ R1 ?2 q& g5 b, B
{
. i. S+ C6 ~ _/ t FormatMSG(GetLastError(), &lpszMsg);. s' ]- b0 K1 P, q
throw lpszMsg;. k' ^2 t1 A2 p% ]* l" \/ q' a5 `
} j. A# J) f# M! Q1 q
5 Q& _" e% n5 u2 Y DWORD i;
7 d) i. Y- Z, r' e H8 r SP_DEVINFO_DATA DeviceInfoData;( q0 O( o# ]$ N. s
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
# K7 i2 k# l" k$ T DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
, w: s% L3 F5 @* s+ @; f
* T% t4 ~, s. O for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
5 s' `5 H4 u' _! \ {" K8 }$ Y; m& Z5 G: }+ C" N
if (1 == nStatus)( f- B* p: | ?2 c" ~1 W3 i; S
{
6 b# V$ s2 ~5 H. N0 H& F! d# g1 h StateChange(DICS_ENABLE, i, hDevInfo);
$ i4 f: {5 A& F o. J }
) C( p9 r5 V0 C, _ else if (0 == nStatus)
- J/ @2 D. ?3 B4 T+ s% | {
! G [; O. M% A% o2 y StateChange(DICS_DISABLE, i, hDevInfo);
1 K l5 H: E+ v+ x4 a } . G; u2 C- u+ x0 Z
}
; ]0 ^; E. U2 @" Z$ d; ?! A% |5 t6 A8 n; |. n( B
// 释放 device information set
# f" E8 ^1 D4 P' m. W0 l9 l return SetupDiDestroyDeviceInfoList(hDevInfo);
8 _+ [' X1 `; D6 B8 t}2 d' A/ R/ `0 d9 Y9 c" K2 H
catch (TCHAR * pszError)9 B) E* {, [' i# I" `8 a
{" b" z+ u9 p1 S9 V& e
::MessageBox(NULL,+ u- k& X" M. E) ]! f5 y2 e# C" Y
pszError,
# {$ w9 D- j V" k" P) g _T("提示"),
; a5 g- U% [; ?6 d MB_OK);
# n; \' H5 F0 b% R if (NULL != lpszMsg)
1 K. _7 U" S+ x+ H" | {
0 a; S' X( ?; v U& W LocalFree((HLOCAL)lpszMsg);9 r9 ^% e1 z/ C
}
6 ~+ F6 `: P) z return FALSE;
1 w$ ]* H1 d9 r, n! r+ _}2 D; q/ E: G2 S9 I4 Q( R
return FALSE;
" v. o4 Y9 x* C}7 s ~. }7 u" V& O' n
0 x6 u L7 n0 {6 G1 X/ f2 ]$ l- V 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。) U. t- T! G/ t0 q; a
据我观察,在注册表的此项下下:8 n2 `# f" U* [: O9 D: I" A
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\& X% F' f6 V! G# r |
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
1 i) L" m2 R3 h- l) E {36FC9E60-C465-11CF-8056-444553540000}4 F, m' y- _0 [- t) Z* ]6 o6 p
这个是CDROM的
' F6 k* D; ?; Q' W8 M {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
5 S/ j- W& o: h8 X I这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|