|
(dlutyuanhongl发表于2005-3-15 23:14:04)4 G f6 t- F+ X0 r- K% b' {
% {" y/ o# [# Z- Z3 T) b这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
, a% i# O) X0 W& k8 j& L$ s// 必要的头文件和要链接的LIB文件" [4 s1 _) i6 I6 M2 d
#include <setupapi.h>
2 i% A9 f/ V. \" g: Y/ v5 I#include <shlwapi.h>' O% E ^5 |; [8 m
#pragma comment(lib, "setupapi.lib")
2 Q) I% f8 o9 C! \" c& b- C#pragma comment(lib, "shlwapi.lib")8 z: Y; x$ V& x9 V$ Z
! U- d$ Q: N5 Z& F: r0 T0 |
// device information set(我把它译为设备信息集), S/ Q: ^3 \# L+ C5 A0 p$ @* N
HDEVINFO hDevInfo = NULL;
% P& G+ }# I& b0 l! `3 D" M$ ~/ E. ?/ G! I
// 出错信息) b& J# y, r; m1 V: C& T
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
. @, L; m4 s( Y3 A5 F* [{ 4 q' n4 U7 K; A! I/ j( q3 A
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM ' Q( m/ g, T4 ^) }6 Y% U& v
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
( h e) f" e i. E, K! T NULL,; ^- Y( \; V: x/ F
dwError,
& P% L o4 l: g8 f MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)," S# B+ w& q! L' R% Y% b, k4 q
(LPTSTR)lpszMsg,5 S2 }( ]/ s& K. V: w, I- `
0,
- |# J+ H, N4 H& h l$ s NULL);
8 ?$ T# p1 V- {4 U$ ?; \! A' M# F2 F! q
if (!bOk)
# G3 `3 ^' t- L2 ]{* ^% d5 l3 }7 \) C/ q( I$ n
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
/ Z2 \: f: @7 |/ @ NULL,
+ b# _% E& W( w: ^1 c DONT_RESOLVE_DLL_REFERENCES);
$ ~5 a' e: ]: Z& ^- s: \ if (NULL != hDll)
2 E" ~; `3 Q8 s {1 }) F" X" R8 v' l* U
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | 9 l- Q( T" U) B$ Q7 V& l/ n* F& H
FORMAT_MESSAGE_FROM_SYSTEM,7 F; G, A' s& f& _9 Z) h
hDll,
5 N3 o% G3 u% w dwError,# C* Z5 z1 T7 a5 [6 b: z
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),8 ]4 c6 F( r" x c
(LPTSTR)lpszMsg,
0 m4 I6 f6 f# O 0,- v1 ?: a5 X$ c" U* N
NULL);
2 m0 I3 k H7 g9 U S FreeLibrary(hDll);# m- A+ ]8 q5 l7 ^
}
7 B% O. F f I* ?6 d6 E, a5 }}
! l& Q& N" y: L1 B. M}$ I& {# z3 |) P7 A. m7 S/ Y Z
" W! l7 u) P! M9 _* o/ _BOOL ChangeStatus(DWORD NewStatus,
: O3 w( p$ e, g- o. Q DWORD SelectedItem, & I( j3 m- o y: l
HDEVINFO hDevInfo)
% ~, v% z5 |4 G+ q) k) P3 }+ `{3 m/ w! g! e# F+ u h
LPTSTR lpszMsg = NULL;% c/ b- _( X$ h) @
HCURSOR hCursor = NULL;0 O: F4 W6 F! L. p5 a) t* z$ E
try
! g7 `4 n& B" B- x{
# G1 G/ b+ A/ Y8 ?* y) S SP_PROPCHANGE_PARAMS PropChangeParams = / D" w3 d2 a" r; }6 } c
{sizeof(SP_CLASSINSTALL_HEADER)};
8 N, b3 G! y, p0 n$ h n! m SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; ) H0 k/ V+ h; }0 V- s4 j9 v$ u% b
% y- c' {2 i3 u q; D& t hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));* l* L' }0 V+ P2 S( h% {5 M& N, A
2 M. g1 N8 ~1 p5 t // Get a handle to the Selected Item. U( ]4 k3 W! x1 B2 W! f$ r
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
' `$ S* |7 S4 L {
1 {2 G4 f1 }# Q( |7 N FormatMSG(GetLastError(), &lpszMsg);; Q! Q! ?/ X( V2 R" @" ]
throw lpszMsg;, _) O( i/ J6 H+ z
}
+ F1 Z1 ?) N5 B6 K" r
# a8 E1 e# z' d, S: l$ P // Set the PropChangeParams structure.
6 n( l/ Z+ g' m3 E! w PropChangeParams.ClassInstallHeader.InstallFunction = . `2 [' Z( s$ p z3 n$ O% D4 F
DIF_PROPERTYCHANGE;2 W' [9 }; ^. h- f
PropChangeParams.Scope = DICS_FLAG_GLOBAL;5 E1 }8 n+ J# l+ p2 d3 `
PropChangeParams.StateChange = NewStatus;# j/ x1 J0 O/ f1 H% g( s
. W7 L7 V5 w# u& @( S
if (!SetupDiSetClassInstallParams(hDevInfo,- N' y1 |( \# {2 P; _2 J6 g
&DeviceInfoData,% H# N* N# i2 J. q1 T! g
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
. u) @+ p% u% c6 {* J- t4 V sizeof(PropChangeParams)))6 V! y, ]0 A* U4 n& H
{
/ v( Z2 ~ U8 _ FormatMSG(GetLastError(), &lpszMsg);
& h# B( F7 q; V5 V4 u( V throw lpszMsg;
3 v. e% I6 G8 L7 k7 u7 N }
* s6 n- k. t% w3 @ l) j& [& n* V, i( X
// Call the ClassInstaller and perform the change.
9 |6 ]# T, l. S& F2 l" }8 k+ N! U% M if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
* W. U8 s% J. T4 G& D- g* D hDevInfo,. B- W5 a! y5 D! Q; B
&DeviceInfoData))
% O J$ r$ T) E+ L$ V {
% @" J3 ~; V6 V FormatMSG(GetLastError(), &lpszMsg);
: o% b6 H% t" g4 L throw lpszMsg;
' p; |% ~) S* |0 R8 I! H0 Z }
B5 {* e0 Y' o0 G* O, l) J$ E
]9 `4 t# X3 | SetCursor(hCursor);
. Q4 M3 {1 \ ?2 K* b; {; d# [ return TRUE;
3 V7 n4 n9 D7 r& R}! I# i0 _0 g/ Q7 k
catch (TCHAR * pszError). c3 h2 ~* q1 E1 I3 C+ p& }
{ O, [' u* m: N4 A1 x Q' [7 |3 b
SetCursor(hCursor);
_& n7 f \" M. W" J/ h6 e. e ::MessageBox(NULL,
* \ c: |+ T+ r7 l5 g7 M0 C* m3 H pszError,
8 ]! M5 M$ g t! ~ _T("提示"),
+ m l7 D% k- m* v7 ^/ W9 Y9 S MB_OK);
. j0 V. O6 F* x if (NULL != lpszMsg)( F4 i$ x: ^7 M j' k- ?/ [
{
: ^, f9 d6 h' o: z' }4 o c! M0 h LocalFree((HLOCAL)lpszMsg);5 d5 C: c+ e8 u" M7 h
}
: G# Y A, d8 X2 T+ m( Q return FALSE;7 n3 b! @; s0 A; h4 ?0 z: d H- F- c
}
0 B; P" \; v! |# u}; ^; M9 I0 h, p# d* O6 d
% N4 F0 A1 B$ J' D3 {// 这些设备的启用和禁用主要有此函数实现# N& H1 Q5 c9 I [ x
// 参数说明,nStatus 可取3个值,-1 :啥也不做* g% c. A& ?5 P* @0 r+ A: ]
// 0 禁用设备,1启用设备。
( s9 K' z8 S7 \# f: R- u2 M# O% ?// nIndex用于控制是对光驱,软驱还是对USB启用或禁用5 n/ B! K% p# O/ i
// 也是可取3个值,0 代表软驱,1 代表光驱
1 p5 p! m/ v7 y ~6 Z- V3 L// 2 代表USB G, P( U" u8 }: u
// 譬如要对光驱实现禁用,可以这样调用此函数
( s, C2 \: }0 a1 C// ControlDisk(0, 1);
8 [; V. C- M7 EBOOL ControlDisk(int nStatus, int nIndex)9 ], w- m" g0 p. a9 f8 a1 b
{
3 @3 B& C2 t+ K: a( N& {. p5 sif (-1 == nStatus): C" y2 Q# e" h2 t! e4 u# n& S) m; ?
{
/ Y+ t. b8 l! e* y5 @, d return FALSE;
6 u. I T* Z) @4 d, h1 v3 C7 g1 }} # h" A; x; S8 O8 ~& Z
9 J3 v# Y& i0 x" @5 b T; P
LPTSTR lpszMsg = NULL;
4 p j7 G0 Z3 |5 s. Btry
) _* E9 e% \" N# U" R* F{
% f V( t' Y; A- d TCHAR * GUIDString = NULL;6 |/ } g, [8 w' u; f+ `9 T' v
GUID guid;$ x8 O+ g8 d( u% u
ZeroMemory(&guid, sizeof(GUID));" P _# B# X& Q+ j
switch(nIndex)
$ p- i7 \+ `7 s6 ]/ w {1 M- z- ~; x" l
case 0: // 0 代表软驱2 t- B: a" V( V2 j+ T
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
; b6 B* T. G3 m/ N8 {7 h" U UuidFromString((unsigned char *)GUIDString, &guid);
/ [' t: X; I( [& ^& H break; ) t9 c! Y* J. L v9 a2 E; H' {
case 1: // 1 代表光驱
6 ]* r% E* }& g: t# F# ^( z GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
; p, S+ a [% P, B UuidFromString((unsigned char *)GUIDString, &guid);
$ v+ ~- Z/ p S% c# _ break;/ P9 N+ u: J( i: W9 m
case 2: // 2 代表USB
/ w0 t3 l& y, S) r8 Y: G GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");* G" m a5 c/ l" B
UuidFromString((unsigned char *)GUIDString, &guid);& V. D( e+ @, h3 ^5 T: V6 W
break;& h& M# c& L4 x5 w- O% G1 }7 H
}; I k+ f/ L% K0 n6 `4 r$ s
9 E. {% S( M& J8 [" t3 ~. }
hDevInfo = SetupDiGetClassDevs(&guid,) ~0 b' b5 c+ ~' H: z3 _& i5 u) @
NULL,* X$ s4 \3 F1 i' C6 W
NULL,( w, d1 X. ]" I; P/ L" V
DIGCF_PRESENT);
( D/ x h+ ?2 t2 u" c5 m if (INVALID_HANDLE_VALUE == hDevInfo)
, T3 Q3 \( a: ]' w" U* O8 S0 q {2 j4 d% Y4 G3 Y
FormatMSG(GetLastError(), &lpszMsg);! j$ u) P- Y% P# ~' @
throw lpszMsg;
0 D7 Q4 b) s5 a' A! J: W" R2 A$ {1 w }" _% Z' k9 y; f( b; w4 d
a1 `7 k B4 D' W
DWORD i;3 P- T4 H3 o4 n+ r& P
SP_DEVINFO_DATA DeviceInfoData;( E% @; I( s. m2 Y/ ^7 k! R# L
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
6 X# c1 I8 N% j( ?7 ~/ r DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);- O- b: {0 E+ |7 X) s; W' |; j5 M
1 K7 o' |8 h& K c! O
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
8 ^, H. v3 p3 \9 I {
; Q+ {" {* u1 ~7 ?2 s7 f6 q if (1 == nStatus)
( H" m: K$ o H$ I: f {
M, A5 A: O8 s! ~. I: B StateChange(DICS_ENABLE, i, hDevInfo);8 x6 d% h2 X% n/ k( H7 {
}9 e+ D% r' |# p+ y
else if (0 == nStatus)$ p# C- R/ V/ k) Q2 V) R* \8 X
{
" ]) i+ A* s% t1 q' ? StateChange(DICS_DISABLE, i, hDevInfo);, @& \" o8 U0 |% E
}
0 I: s5 }. Q1 J7 \ w }
1 K5 e5 e( }# z: I- S% x e- H9 V) Q9 I l, z* x+ U( E. ?
// 释放 device information set4 X0 n3 ]: F& p3 V$ l$ N9 [3 n' a; v
return SetupDiDestroyDeviceInfoList(hDevInfo);
5 X$ p( G* P* V8 n$ i; ?, g; Y}
+ v6 O9 U* u, v2 ^: M7 U9 q+ Ucatch (TCHAR * pszError)
. t5 t0 l# z) f4 Y{
- u; `5 K9 s: v ::MessageBox(NULL,
$ y6 [: [; A! _' `" r' D& C+ b pszError,
6 N. K1 Z( w2 Y) h0 f# L _T("提示"),. v! @; t7 {6 O \0 }" O1 {6 P8 y
MB_OK);
% |& U/ y3 w) X5 m. V if (NULL != lpszMsg)' C( r, W# V4 t# h; [9 {
{4 D1 F* D6 g7 g2 b, S
LocalFree((HLOCAL)lpszMsg);
9 h, E( [" R+ V p6 \/ L } t! y7 Y+ o# a9 P/ A
return FALSE;
: c4 i+ w1 ?9 ]6 H! N+ O}
2 `1 e1 a/ W; [: l( Greturn FALSE;$ o. x8 d# V( e ~7 Z0 g6 s4 A4 D8 O
}
. y2 z6 y9 \5 K% j8 _# J0 V- Q0 s; ]
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
1 d1 k+ `. F- D% a: p 据我观察,在注册表的此项下下:
* R9 E' H/ K, r7 }7 o8 w; ~ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
0 [& S2 X* F6 }5 R6 s1 C 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
4 q! A9 e" B. ^# s7 Z0 K- { {36FC9E60-C465-11CF-8056-444553540000}
7 a# e& e' p! P: F2 D 这个是CDROM的
]4 A7 c8 Y9 M' P8 ` {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。% k9 u: m' s8 N% J
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|