|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)0 _! `# e! V' r
5 G& W2 E' Y; j u! v# P/ h
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
+ S! a" S, G3 A& z// 必要的头文件和要链接的LIB文件3 b- v; o+ A1 G! q
#include <setupapi.h>* Y0 C9 ?: E$ W# p, Y
#include <shlwapi.h>" w1 p2 ~: y5 {2 R' ]9 ]7 E
#pragma comment(lib, "setupapi.lib")0 Y8 i6 O" L, k( i; p5 K- z
#pragma comment(lib, "shlwapi.lib")
1 k e& H: `' a
& J/ e- t* L2 B; C3 P// device information set(我把它译为设备信息集) D' c4 K$ W( {; w( s1 A$ z
HDEVINFO hDevInfo = NULL;
/ [7 b O) b# K- G, @) l
8 h3 X' M2 X" P- w8 N9 c4 X6 i// 出错信息8 H& ]; I7 q. O' _8 S" r3 ~6 I* o
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)7 y5 R( M1 O; {8 H
{
0 e, |& p {5 ]% W0 i BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM * d2 [) y' q7 U+ p: ~
| FORMAT_MESSAGE_ALLOCATE_BUFFER,1 `3 `+ o: x9 a: k; P* j1 u6 s* f
NULL,9 u b6 @# s: k( F
dwError,5 c; F/ j1 c9 O e5 m7 A$ L% j
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
8 z& _1 \: {' ?7 O4 k (LPTSTR)lpszMsg,
5 U, @$ C/ y3 {$ B$ L- m 0,/ s" }/ o0 }6 r7 P ?7 x+ U
NULL);
& _- z) l. p5 x- ^
4 K+ q' o2 ^1 A i, }if (!bOk)
( A1 d# W9 _& K1 H: T{
( [* v# ~, t% U/ W1 l) o$ V HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
, {% q2 E7 J" ~2 d3 v- [9 Q NULL,& o. k& T* w1 m" `5 Q
DONT_RESOLVE_DLL_REFERENCES);8 C$ g3 o8 s! m3 v5 s. s; Y
if (NULL != hDll)
2 O2 g5 c% }. ^$ l% M6 X {
5 N- \, {5 P7 M% d5 m4 z FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
9 t/ ^; x' Z0 w/ D, F) U FORMAT_MESSAGE_FROM_SYSTEM,8 M3 \* N- ?0 u2 v4 y P. Q
hDll,
9 \, a9 H P' W. ^6 U& V, @ dwError, F2 U- i; g! z: i3 M6 t
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
. A1 \' }5 I k (LPTSTR)lpszMsg,
9 L# \1 N# W% _' B) j% [ 0,
; w/ E! G! z: a0 a% p NULL);9 {" E. g d* E. G. ^3 P1 |; ~
FreeLibrary(hDll);
4 O, `. s1 d* Q ^$ v }" ]# e9 |; O; o4 |; P e
}( h/ s, t- k! a0 m1 _: N, s
}- K! Q2 x/ v8 J7 _* V2 S
, @: \: u& d- r4 A" i4 [9 hBOOL ChangeStatus(DWORD NewStatus, 1 U, c" J; d9 i
DWORD SelectedItem,
- Q$ @" [/ V. i: \' l5 S HDEVINFO hDevInfo)2 @4 h/ f4 f% S/ r9 l+ ^8 Y
{" F8 G" K- |; ~' b4 v1 w
LPTSTR lpszMsg = NULL;+ B7 N/ w2 K8 Z0 i
HCURSOR hCursor = NULL;% o' _: g, ?' f4 v% p
try) E) b, f* I3 o# l/ E" E' z
{! o' o1 ?. C1 g2 P
SP_PROPCHANGE_PARAMS PropChangeParams = : M% M! Q+ x6 @5 H) f) A+ ~
{sizeof(SP_CLASSINSTALL_HEADER)};
1 s1 O6 [$ N8 C6 m SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; & M$ f7 a) o9 j4 x) A, W
2 I7 c. |8 J" m9 d( v8 w; \ hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));$ G9 `9 J; I7 s& f2 m/ [' x: Z+ w" \
* i' a6 l; e+ y; S+ T) d; C8 F // Get a handle to the Selected Item.6 D2 _) J+ [3 x" t) L, A" e
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))+ g7 K# K& n/ Y% P, V$ q$ b5 }
{
& I/ f2 _9 b" H7 O+ u' A& \! ? FormatMSG(GetLastError(), &lpszMsg);
9 H7 l/ p1 {0 \3 @# g$ c& O throw lpszMsg;
2 |2 U0 s) X7 n6 D0 V }, q2 c/ M; {8 E; ?) e* u0 D
' h' z: O* B+ s6 ?' p& q // Set the PropChangeParams structure.2 Q- t- X* u4 D8 {( O
PropChangeParams.ClassInstallHeader.InstallFunction = ( T, Z* j# ]7 H
DIF_PROPERTYCHANGE;$ D$ `! c1 h2 S- O: n" r
PropChangeParams.Scope = DICS_FLAG_GLOBAL;; T" O) p' W( I& t. _& |& {
PropChangeParams.StateChange = NewStatus;
7 A+ f% Q& Q' H5 H$ e* S: P7 E2 H# J8 [. I2 R/ @5 x8 n
if (!SetupDiSetClassInstallParams(hDevInfo,9 \# N$ I' V8 b5 j
&DeviceInfoData,
7 g! ~- b. L! Q: Q (SP_CLASSINSTALL_HEADER *)& ropChangeParams,1 A( z) |/ u& G* c4 c" w3 k& `2 f
sizeof(PropChangeParams)))! l' C5 _! s( V+ ~- _$ h
{# S: O8 x$ n7 w. U! _1 C3 E' n- l2 ^
FormatMSG(GetLastError(), &lpszMsg);
+ p0 P! N1 ]: t) o/ x throw lpszMsg;
3 @4 E. v# E* `6 v- I9 T% b }3 b, t$ D' {& o" T
9 @) B, q/ Y! l0 k
// Call the ClassInstaller and perform the change.
- Z" b+ G3 F" l* a! [1 X if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,7 s) C- B: r' w
hDevInfo,2 P- u7 l" C2 h: V+ I& @
&DeviceInfoData))
$ O! S! b5 v; F& O {) M5 y4 b* P6 B% p2 s0 I3 d
FormatMSG(GetLastError(), &lpszMsg);3 n$ D' o/ P* J p3 W2 @$ u
throw lpszMsg;
8 w5 k. \! D8 j3 _0 f' T( f: R- }. w }4 G& s0 S) w z' y2 [
* O+ {# J1 q; g/ g3 }+ s
SetCursor(hCursor);
; U- p% d2 w! Y, ?( w return TRUE;
" f/ L9 \) U3 d+ ?0 m}' `% ?7 X% X. _" |
catch (TCHAR * pszError)
+ l5 P3 w3 l: G) L/ N. m{
& o+ W: M, O+ S$ k0 N# W4 ` SetCursor(hCursor);
/ l: a9 w5 j) {+ y& r' F( D ::MessageBox(NULL,! g' r8 \5 S' R$ k! Y" r6 K
pszError,
) N* ^% X; ?8 s( s5 r _T("提示"),
0 r+ B8 I1 B) I MB_OK);' Q9 A" [* I4 Y
if (NULL != lpszMsg)
, u H, E2 O# j* F& `6 C/ q3 L0 z) y {0 i9 _8 Y3 `" {
LocalFree((HLOCAL)lpszMsg);
: @6 K0 f- e& t+ q( l }
6 o2 {" f) N6 a+ T- I9 I& N- V return FALSE;
1 a; H/ S+ j1 `' \" ~7 s) M} + d$ v5 I3 c0 B3 J! [( b
}
4 L# P5 u4 v7 N! q" |
( ?! K5 R* [! {6 V2 t$ W// 这些设备的启用和禁用主要有此函数实现3 T, w7 @' u( P; D8 S& S) K* r
// 参数说明,nStatus 可取3个值,-1 :啥也不做
7 ?* o) I& M( C4 H) V+ o# w// 0 禁用设备,1启用设备。
2 S0 R. m* ]7 J8 _// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
* O5 T4 t5 J# z5 _// 也是可取3个值,0 代表软驱,1 代表光驱4 @- g8 H: t! |( p4 B2 q/ C7 K
// 2 代表USB7 D9 g5 U# b- [' O; ?+ W0 @( w2 U: i9 V
// 譬如要对光驱实现禁用,可以这样调用此函数& ^& V# [( g% X: a2 |7 E
// ControlDisk(0, 1);, C4 ^6 b- z+ ]( g0 f% z
BOOL ControlDisk(int nStatus, int nIndex), G/ H3 o5 @" ~3 t
{# S# p: s: E3 Y3 R% u. s
if (-1 == nStatus)* h- Q# p, @5 f! j) L
{- O4 I# D5 T5 k" I- U/ U
return FALSE;3 f8 I3 u! S/ P6 N& P/ a
} + z4 i6 C7 i- e
3 d% {1 X. J+ E+ ^2 N, tLPTSTR lpszMsg = NULL;, z! [+ W( ~8 `' f* G
try7 d. s% y0 l5 B0 F" y
{# h9 U7 Y& p$ m* N: Y
TCHAR * GUIDString = NULL;
$ a) p1 g: L0 C, ` GUID guid;! I) \9 k. \- Y
ZeroMemory(&guid, sizeof(GUID));
! ]8 u w( V' F! x switch(nIndex)
. h$ P4 ?' ^1 b; r, l {
, P' i) x5 t, g2 B* P case 0: // 0 代表软驱5 F# O' R1 ]7 M
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
+ F7 |5 ?7 ]( @. j: e UuidFromString((unsigned char *)GUIDString, &guid);
0 h+ a$ @% n5 _' V6 G break;
7 |$ L; f0 i* W case 1: // 1 代表光驱
& g1 _ t5 {, b- ^7 m GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");2 v/ S& U- ]6 b1 j0 g* l
UuidFromString((unsigned char *)GUIDString, &guid);
( I @7 p1 P6 W, T break;$ Y" a' n1 s+ o1 v0 M
case 2: // 2 代表USB" M& d! l, g& [! n9 N. i
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");6 [- j' I; I- m+ F
UuidFromString((unsigned char *)GUIDString, &guid);
5 }; b( h9 x% v8 |6 M9 [$ v break;4 Q, C4 F! ?' m+ t& R
}
% E4 B8 Y* c+ e) h" }0 n$ K- m) W( B" X
hDevInfo = SetupDiGetClassDevs(&guid,
, Z* N5 W: G; y; E; B5 C NULL,* F* Y# D- w8 g5 z& W9 d- P+ a
NULL,
8 _, d* _: o. h1 ?% r DIGCF_PRESENT);# ?% O" m: e+ D2 d8 ~" m! S
if (INVALID_HANDLE_VALUE == hDevInfo)
7 I; [2 d) n) G0 T/ O! Y1 d/ l {
/ b' \" a" G. e5 K FormatMSG(GetLastError(), &lpszMsg);
( e* O4 R& q) r$ F8 j throw lpszMsg;0 n; a5 X# W2 _/ j8 a' j. }5 I
}
& g* D2 g+ L& W1 P5 v+ ]& h" P; D) C7 y& \6 j( k6 M( S
DWORD i;) D3 t/ n" l a
SP_DEVINFO_DATA DeviceInfoData;; S2 j2 P( [- W: d4 x
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
: S1 @. L8 ?. V3 U) N- p DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
* Y$ l0 Y2 D2 s7 I' ]
1 J, j4 g& o. ~/ \; _4 M, { for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
. }2 X3 B0 l ^! ]+ e& [7 Q {' [: h1 o3 t% E2 P8 A7 q+ ~/ l
if (1 == nStatus)# A* L7 O/ ~: S5 W
{2 V# Q' [1 Q; q& m, l' }
StateChange(DICS_ENABLE, i, hDevInfo);( r( E- H& [, O- d
}
& B( N) Q+ }9 [$ M& q else if (0 == nStatus)
( \8 i2 X/ g! E; k {
' _* |: h4 U. B7 Z2 p" Q StateChange(DICS_DISABLE, i, hDevInfo);
+ |' `; b$ p. o+ D" `5 `" ?7 U9 J5 o) d } - U8 L% Y& x+ K. \+ j7 K& a; t; `
}* ]+ I. K' C& J
( O% \) v- ]: l8 m4 I; q) L. Z // 释放 device information set8 C+ y6 m3 d6 q; h% l& E* f9 y
return SetupDiDestroyDeviceInfoList(hDevInfo);
3 F0 D% O$ u9 Z6 d$ l* I+ x$ a; |}
- z$ r9 H e7 k' icatch (TCHAR * pszError)! ^ \3 w2 C6 K: x* C% x9 a8 g% K
{; R/ W6 Z& K% u: m+ a/ ?- M
::MessageBox(NULL,, l- i e7 q9 M+ L$ J
pszError,
1 V1 D$ ^) G$ D# K6 u" n _T("提示"),( Q9 g, T5 T' R2 z% f4 M4 Q- M
MB_OK);
2 w _9 M6 P5 P; k+ ^ if (NULL != lpszMsg)$ z8 p2 q2 o% R* E( ^& ]$ k
{
$ T3 u3 M& B) u" ?6 A7 S7 g LocalFree((HLOCAL)lpszMsg);
# c8 w) v3 g$ z* O# N1 l } $ p5 @& V, e% O+ K/ E. F8 w' a- e
return FALSE;
) _* d! p" Q* b7 c( V5 H; n" \6 ~5 t}2 O+ @( ^' U& A0 R4 i: C6 ~
return FALSE;
4 r" {2 F! T: \4 F7 E}+ k& j% n& E6 e/ @/ `$ ^
6 e0 s) q4 ?0 h
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。, c4 X0 Z% \3 y$ Z! W2 {9 ~2 `
据我观察,在注册表的此项下下:. D* f6 I% F# K k
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\% p( N& @) F- t3 M# ?) c$ ?
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
' ? h6 @1 W3 z# s/ L \2 } {36FC9E60-C465-11CF-8056-444553540000}
9 u" d9 i) Z3 t5 I2 i5 P* k, ] 这个是CDROM的
- A9 F% c+ B7 ^5 Z- h5 |8 A {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。# ^1 ? s* n3 N* r
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|