|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)7 Y/ l# Z: w( J: Z
2 h" m4 c- k+ ]! I
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:3 I, T P" ?9 B0 r
// 必要的头文件和要链接的LIB文件. y' e! o: T( b
#include <setupapi.h>
; w/ g! k# {2 }$ X! g8 c$ \#include <shlwapi.h>5 a. G6 Q* z/ `) _; H8 {( R9 ?
#pragma comment(lib, "setupapi.lib")
/ l) Z! ~8 z3 x: L" N% G* Z Y0 r#pragma comment(lib, "shlwapi.lib")% C9 n6 w9 i( i
) M6 {: P1 u; q8 g/ Y* S
// device information set(我把它译为设备信息集)
. I# z- P j% a7 H3 x; d2 c- f K7 |HDEVINFO hDevInfo = NULL;
8 ~; s2 s9 r7 _ a( `/ i
" z) g6 v! b2 K+ E1 C1 S// 出错信息2 j! | w" i9 H1 P1 k
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)1 ~. R, e7 r2 V) F, ^$ U7 i8 @
{
2 c, N& H% _7 `# j1 m BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 7 `2 [! S: S3 Z8 V: U) b
| FORMAT_MESSAGE_ALLOCATE_BUFFER,4 ~9 @. y$ t0 |! z4 ], t
NULL,
, I, B \, p. c- w( U, W dwError,6 f5 R+ D; }% d) x
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
- Q" i( r2 K; K3 K (LPTSTR)lpszMsg,0 z3 [. M) }* G" z
0,
# L5 p# I, j- z* i8 c2 S NULL);# f( X f* N- D1 X7 V
& ]4 N% b! x' iif (!bOk)
0 B4 Z& [* c( `9 y1 I/ |4 d# ?{
& H9 R" n x! R/ l' v4 F* t7 [1 s0 p HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
: q9 a: q/ F0 r! F$ x5 o NULL,
6 [0 z! j( D/ a DONT_RESOLVE_DLL_REFERENCES);
6 \/ Z3 ]/ ^3 I2 K3 t5 L if (NULL != hDll)
' A% r! u1 o4 t {9 K" |" c3 E" F7 M4 X8 | P
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | ' W5 [; G5 R; \& o" D
FORMAT_MESSAGE_FROM_SYSTEM, Z- g# q4 E1 b& s4 o
hDll,
8 t9 b" G4 y) i d dwError,0 V, ^, n* o2 V V, I
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
% j" i: t9 R6 g+ X8 H2 } (LPTSTR)lpszMsg,1 }6 S+ E8 E3 ~5 ~& v/ H7 i
0,0 j. u/ h0 E4 T
NULL);
/ N3 T( E' ]0 C5 W9 C$ ^3 C |" n FreeLibrary(hDll);/ U2 ^6 B7 l! D" q% l& E1 h2 Y
}. ?+ `' G$ Q- F/ ?2 r n7 f
}" f! O$ j& N. i( W2 I' z
}5 l% h; q) ]' h0 X9 N
# X1 ~3 M" w8 Q; W$ U
BOOL ChangeStatus(DWORD NewStatus, 7 i k* L o( a! Z9 @ p
DWORD SelectedItem, 8 u/ s% O8 Y0 O
HDEVINFO hDevInfo)3 C1 @/ G" H7 q
{
/ a2 Z* {! H0 n, G; |; tLPTSTR lpszMsg = NULL;
- y- o7 _ N* X5 S P# AHCURSOR hCursor = NULL;- i2 B8 c* z$ M, |7 f& H4 K# |' B# m1 C
try
4 E' `1 r: ~" q{
2 ^# [) {0 @2 j) y" U5 C SP_PROPCHANGE_PARAMS PropChangeParams = & N. r2 q" R$ Q0 e
{sizeof(SP_CLASSINSTALL_HEADER)};' m% J* y6 _- [! S! \! J- c$ i" H
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 1 u. {0 S6 X2 i& N
. j; A6 q& l/ f; e! s hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); x5 ?9 j# Y# i k' H
3 @$ F5 O* A7 N8 y2 M# z& z // Get a handle to the Selected Item.
) a: b8 a7 ^# D6 i4 C5 B if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
: p) L( t9 B; w6 G* ^+ W {
. C# H- x# p: E0 Z' J FormatMSG(GetLastError(), &lpszMsg);
2 |$ G' s4 O' U- a5 ]' X5 B; M ? throw lpszMsg;
+ W8 E' v; s- J( i+ j' b- b }% v! R, y8 d+ ^
; H8 u: F3 w* Z. k // Set the PropChangeParams structure.# k$ h5 u# W$ q7 j1 y' U6 p
PropChangeParams.ClassInstallHeader.InstallFunction = $ R3 h! d2 w; Z1 }
DIF_PROPERTYCHANGE;7 B3 u3 {6 r0 j; R* d2 a6 R0 ^$ Y$ X q
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
6 T5 g4 p P# T+ s; e h, y6 J PropChangeParams.StateChange = NewStatus;
: L7 j3 l' b8 A3 z8 q" r
. L( D1 h7 {" F# S& |3 A if (!SetupDiSetClassInstallParams(hDevInfo,
1 k) o& Z! |- J+ @4 h &DeviceInfoData,! b; j9 a O* n( i7 Y% l
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
4 y, r( v, Y& X! r sizeof(PropChangeParams))) B' O7 o/ m" p/ c
{
3 J5 J1 y8 Q5 G/ C FormatMSG(GetLastError(), &lpszMsg);; g' p3 T; P) H
throw lpszMsg;
& K' q. y* ^6 A" c6 I5 R }
* A9 f9 O2 T- [# T- i) w
! `* s) S( I: {. y2 A8 D( W6 I y // Call the ClassInstaller and perform the change.
, p* b2 i7 d% y8 g& ~2 x8 F if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,- L' R! n" t2 O B$ D" f
hDevInfo,( ^. l* }+ |, B/ n4 r/ t# }
&DeviceInfoData))3 ]( v7 @5 ]1 \% t0 q) b
{/ k }* q. u8 J2 e @/ f3 E3 Q
FormatMSG(GetLastError(), &lpszMsg);
2 T5 \1 k, x. v( @, _2 ?3 J throw lpszMsg;+ m2 R( C" t+ a# b9 x
}
& g/ o) s2 G4 s& J
/ m+ _- H' A- d* R SetCursor(hCursor);
* w6 d5 ?( J) f1 d( z) Y return TRUE;* s+ ]: g# |; Y' E6 B8 R4 S5 ^
}
5 [, X" n: V- E _# U& }catch (TCHAR * pszError)
$ V7 A* l- r& }6 N5 M* @( @{4 ]( y- n# E$ |
SetCursor(hCursor);( D6 @# \ i8 T4 A9 J: y
::MessageBox(NULL,8 Z: o9 O! L- c6 r; B
pszError,; `3 R! x% m+ G% A+ g* k
_T("提示"),) m# @8 B" a6 K/ S1 P: v
MB_OK);
8 P3 d9 l/ `* q. K if (NULL != lpszMsg)# h/ M; h- E2 j C. ?1 @4 t# }
{
4 V7 g8 W% n& D( z LocalFree((HLOCAL)lpszMsg);/ m B/ M- \7 Z) F7 x4 N. Z/ ~
}
8 X1 n7 E3 A0 _2 Y4 B( w9 r! v1 q return FALSE;# a- W) @! S" c2 r$ l
}
/ H8 f6 _$ U' B" \8 I$ R/ w}# q. [4 [! f. [: D
4 m2 U A I9 m8 e, N// 这些设备的启用和禁用主要有此函数实现5 z3 L# f# H7 r4 `: n
// 参数说明,nStatus 可取3个值,-1 :啥也不做1 m% A' N4 @+ E% P3 w
// 0 禁用设备,1启用设备。* h1 v& W( a0 S9 s
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用* G' U. l" g. ` n
// 也是可取3个值,0 代表软驱,1 代表光驱$ I1 _# R' S' F# E1 ~# b, P7 u
// 2 代表USB u+ q" E: q2 ^ ]
// 譬如要对光驱实现禁用,可以这样调用此函数
# D9 _: }& b% ?" e' G y; ~// ControlDisk(0, 1);3 e$ [5 ]# _1 X% ^2 {6 s! S$ V
BOOL ControlDisk(int nStatus, int nIndex)
& k/ U5 f6 N3 B4 z{
- A2 o3 E0 e, o9 f# C2 Y, Hif (-1 == nStatus)% E" V9 D$ Z; c
{
" M0 H' ~) ^1 B return FALSE;
; Y" K! _) K& Z}
0 ]3 J, w6 g+ B: p" q5 p* J! k$ h( `# D! i
LPTSTR lpszMsg = NULL;8 O! e( I4 d+ y4 d) J" Y
try8 N# x6 k# ]/ ~
{
9 C+ j. Z2 z1 S4 n0 ~ TCHAR * GUIDString = NULL;# C3 w( Y5 }* W }
GUID guid;
* Z& O' ~* r+ C2 ] ZeroMemory(&guid, sizeof(GUID));% Y. w3 ~6 _% [: G. i" `; U2 c& D
switch(nIndex)/ y& t& S/ r6 X/ ?9 C! o: F
{
4 n$ h' ]' o0 N8 | case 0: // 0 代表软驱
+ S/ d# Q* i. s9 L5 a* { GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
; z% J: D4 k6 `9 C9 U: J( I UuidFromString((unsigned char *)GUIDString, &guid);
; u( a* j9 _, f; D2 l/ N break;
( T1 f \* n/ w ` b) s! h case 1: // 1 代表光驱
0 p8 S# c: e- H) A2 T- Y GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
4 I% a' O9 ~- F" E. B6 f( X- ~ UuidFromString((unsigned char *)GUIDString, &guid);! ^! ?1 J6 }& B3 a$ v) r' L* Z
break;
3 _7 }/ p: k; Q: B case 2: // 2 代表USB1 v+ N6 t* T) U" y0 R0 q% V
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
% \; {9 k& h5 \, H( J UuidFromString((unsigned char *)GUIDString, &guid);
$ ` _ \+ c9 y' m break;
4 A& L: `- \% K }
" C, z2 `8 O2 P# U, _, I" P% S- M
hDevInfo = SetupDiGetClassDevs(&guid,/ E& r* U! j0 p
NULL, g* K3 _1 l x0 u; h' H
NULL,
2 `# h+ P5 w5 B) c) I! o. p DIGCF_PRESENT);, {+ y1 F8 H. B4 _) ?
if (INVALID_HANDLE_VALUE == hDevInfo)3 o8 L" Z( j* o0 m0 q9 O' H
{
+ S2 q% k; s5 k3 [0 K0 H FormatMSG(GetLastError(), &lpszMsg);" I- f( p, L' Z% C$ x2 K
throw lpszMsg;7 g* Y3 r6 \# F. E
}
0 c& i9 B5 d& H( }2 N, B% Y% q6 ~ ~3 w6 p
DWORD i;+ S- I& x8 N* `; E
SP_DEVINFO_DATA DeviceInfoData;! w- R0 ]6 F) v. |
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); ~. m0 Q, w# t& Z, R
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
3 a Q6 u4 O( _8 K& v/ w; I
# m7 @0 D; L% S2 i% g- A% n for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
8 @; c* e$ F+ i* Y {1 w1 K/ G0 I. A( Z$ j C
if (1 == nStatus)
. ~' L- J) V" l: d- t7 Y" k0 }8 D A {
. N U/ v! t T6 P( Y4 T StateChange(DICS_ENABLE, i, hDevInfo);
6 _: S# [# S2 l( w6 x8 w }
6 _- B) ^9 H7 t0 h$ q# i( | e else if (0 == nStatus)) P+ y" h1 u9 d& N* E$ C0 t
{- h, `, U$ y# u
StateChange(DICS_DISABLE, i, hDevInfo);5 U8 C+ v5 [# Y% @; C
} 1 a# J" S: V: R! b; ~8 l" A
}
/ k6 C# D/ r/ }$ T; T& v1 |0 o
0 Z; h F& X M4 x5 I // 释放 device information set( V9 c9 Z+ |0 ]9 h+ [' g
return SetupDiDestroyDeviceInfoList(hDevInfo);
) I5 o, a. I$ G4 }; ^! u- O}9 w% X* f; P( {1 A4 [/ u0 T. h
catch (TCHAR * pszError)6 p( Z% i5 k$ r/ A5 Q( M
{
# a# o) M5 ^6 U0 ^. Q% y/ ?; V1 w ::MessageBox(NULL,( y9 {: j( o. u8 O
pszError,' i4 ~& D2 G% c+ H d$ O: _& M* s1 A8 F
_T("提示"),
8 D2 \8 _; w. z$ R# f* H) r MB_OK);4 ^3 Y/ f) k5 \9 v( ?6 ~4 ~
if (NULL != lpszMsg)9 @/ l. ]7 b& E& c; g
{
. v+ P0 Y) \0 e+ |- K: V. v" q LocalFree((HLOCAL)lpszMsg);' E; x" r) y s1 {- |( |
} + V7 {8 M. s) B& ?5 v( K! ~' i
return FALSE;
& Q# D+ o4 x: S0 Y5 ]1 G}9 ^4 U* D. V, Z2 ^; D, n( [
return FALSE;8 ^; v7 [' C0 x2 y
}- f4 T \" W% U, A
7 q! | e, ?: j8 E9 P
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
/ }3 A% G+ H! W 据我观察,在注册表的此项下下:
" y, K+ |; O2 `1 p& M* t HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
8 T/ d9 g+ W( d8 Q. Z6 T5 P( {# V 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
, J" z1 F* r9 w {36FC9E60-C465-11CF-8056-444553540000}& {2 q* ~4 v6 {: w8 g3 L
这个是CDROM的0 T' a6 f' \$ L& N& i
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
' y+ P, z. G2 S9 I$ i9 l. Y这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|