|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
$ }1 K* V' N4 [$ Y/ \* t2 T7 r4 z& Z
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:' R" R p' z) b! i% z% v# X/ \" s
// 必要的头文件和要链接的LIB文件
J0 U- y# z; |/ g+ h#include <setupapi.h>/ M# N; Y) T9 }! l( P
#include <shlwapi.h>
+ y+ p" N7 F* x/ Q3 T* Y#pragma comment(lib, "setupapi.lib")/ ~3 M. W! E; \7 K7 B9 f
#pragma comment(lib, "shlwapi.lib")
g: J$ n9 d* m+ H+ [- _( |/ @1 b: C s) e
// device information set(我把它译为设备信息集)' ~: ~, F$ d1 s) T( J
HDEVINFO hDevInfo = NULL;
5 e7 V+ z, F7 `0 O& h) H) d( B' j3 {; \7 l5 ~
// 出错信息
4 b- |2 S- Y/ J8 Z4 U' N% Bvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
6 f' T8 ]; `4 \* ~; U; t7 \+ o{ 5 P* x3 |0 p( w& T; ?, y
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
9 A" \, e. a' m* n | FORMAT_MESSAGE_ALLOCATE_BUFFER,
/ K0 f1 c/ ]' H2 z! i NULL,2 N; K* r! g; V# g* L# O8 a
dwError,4 b/ y) j, [ }0 }3 U
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
/ Q0 a/ W s, D (LPTSTR)lpszMsg,
/ O$ p) q2 V& i6 V& D8 V$ {. h 0,& u! q7 z5 u2 I: P: ?5 P8 N
NULL);9 Y: T. A2 Q' V- |8 ^! `, q
7 h* e' e% u6 B6 ?( T, J
if (!bOk)
* M. ]7 D7 O) F+ b0 A{. U3 ~: Y; b/ w& A; j, R0 `# ]4 ~
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
: |# e( q8 a6 l+ T& i6 Z NULL,
J* g e: g- L8 B DONT_RESOLVE_DLL_REFERENCES);1 C4 O+ F" C6 L7 k$ u
if (NULL != hDll)# h$ I. ~3 Q3 U& ?3 b, I+ N' Q
{
) I* ~8 U' g. m7 B FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | 6 i) \9 K+ ]- S# a2 b% `: x; b
FORMAT_MESSAGE_FROM_SYSTEM,
# ^/ A) R4 L& r0 c hDll,2 ]* M% I1 X; i, _& P
dwError,5 U% G& B) R% W: }7 m; L5 t5 j) u
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),2 l+ ~+ U: P. [4 r
(LPTSTR)lpszMsg,+ d7 N& ~& m- t! E* M' i" [, K! x
0,6 W; }! l$ w Q f+ y& K6 S) b/ L0 ?
NULL);
( g% ^- c r$ r& e FreeLibrary(hDll);8 R' ~' A. Q# Z6 T
}8 y% Z7 Q/ e7 J0 z1 [8 v
}9 T' N' i! h3 s8 {
}4 G2 C, d- }3 n- l
2 _5 f2 _( J- Z) o1 a8 W5 K7 b
BOOL ChangeStatus(DWORD NewStatus, : a$ J, Z5 g! n, ^6 G
DWORD SelectedItem, ) a6 G. k% Y6 d1 S7 z$ K: s2 [
HDEVINFO hDevInfo)
# g7 {4 r+ Q! W$ L- t{
' X. X( E7 p7 ]% n8 OLPTSTR lpszMsg = NULL;* H3 L; r3 z: ~4 A0 G7 Q
HCURSOR hCursor = NULL;+ h c& L7 B0 _1 d2 D T
try8 Z: A( z/ U8 N5 Z
{, b y/ z+ Y2 m6 k$ K3 e3 y, o
SP_PROPCHANGE_PARAMS PropChangeParams = $ J+ \5 F, E4 C
{sizeof(SP_CLASSINSTALL_HEADER)}; Q- B8 o9 r% O- b
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
7 s" Q# l. h& k' l, Y
) ]) J/ z$ U( ]+ L, Q* Q+ U hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
3 K; W3 C2 F3 O1 s' U3 Q. c% w) T
9 m0 q5 a& \ \# s7 \4 D! a5 H // Get a handle to the Selected Item.
9 t( R; M8 `3 J if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))" u6 ^4 ^+ P9 z8 K
{' E' h: ^& K: S$ b* I
FormatMSG(GetLastError(), &lpszMsg);
8 @" U/ t4 q, s/ u) U X) | throw lpszMsg;) F+ z! o& m! H' T W
}( A$ s0 O2 R1 }$ S: S7 `+ s6 X/ N
6 J4 d2 x; g! v1 L) \* ^
// Set the PropChangeParams structure.
. |5 I/ Z3 E7 v8 a D PropChangeParams.ClassInstallHeader.InstallFunction =
; W) V+ C( D) }" x# O DIF_PROPERTYCHANGE;. P8 L4 \! @. G( K3 S) u
PropChangeParams.Scope = DICS_FLAG_GLOBAL;6 E4 l$ ]/ @) R2 U3 I: g& U
PropChangeParams.StateChange = NewStatus;% v0 a* ^* s4 t+ @$ h- t5 V) F
" c* d% C2 Z: ?5 {& u if (!SetupDiSetClassInstallParams(hDevInfo," h4 ^- V U* a) Z& I4 \) d- b
&DeviceInfoData,6 g: j* R, N/ s% ]
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
5 x, Q& a) X$ T sizeof(PropChangeParams)))
% [ v% X0 b; W) P) N5 R$ I {
7 i9 R* x2 i. v6 q FormatMSG(GetLastError(), &lpszMsg);
) L1 t0 ?. C% S throw lpszMsg;
4 S# P3 e: F, J( [ }' B. d1 M2 t* K' `
5 B8 U/ @3 \% A/ `/ u9 [
// Call the ClassInstaller and perform the change.
& g; j0 }- w7 i; w if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
, x$ h2 I+ V" F. |* S X1 j hDevInfo,% }# o9 \2 E6 ^& }- X) f% s
&DeviceInfoData))
% B% l9 D% _/ m. b( z. n8 g {' v& F/ E9 }6 K8 j0 E2 s
FormatMSG(GetLastError(), &lpszMsg);+ e9 T1 ]5 W6 s; B9 [
throw lpszMsg;1 U7 C5 y0 u% _* G: U5 e7 b
}7 d; ]: J: N, U% w7 |- e1 c
, Y5 ^/ A" ^) G
SetCursor(hCursor); ; h4 `: r C2 L6 X1 K( p
return TRUE;7 l3 g; }1 B; c" z" P) W1 n
}+ l5 D, r: T$ n, g+ b/ z7 ?- ?
catch (TCHAR * pszError)
1 [# z1 F) y% V{
% A+ u, v$ D8 s+ t2 V2 J* M7 U" H SetCursor(hCursor);; t" `( f# ~2 _# X1 u% F' J; U! S
::MessageBox(NULL,
0 ]9 Q9 e& d. w0 y pszError,3 g/ n* Q% r$ W8 T, F- `) r
_T("提示"),
; c1 z" R6 }, m! d4 {2 @ MB_OK);, t6 n+ o# w7 e9 X a
if (NULL != lpszMsg)
1 O" |! d' O' m7 p {# C" ~" b( |+ Z# Y( l, V& k% t
LocalFree((HLOCAL)lpszMsg);; k, D" g& s; q% i/ ?
} ! X" j! c+ i- R! q
return FALSE;- P4 y" j/ [- v5 }; \) M
} - g& s$ p. D* l% B4 I- F0 m
}6 E3 k' w0 k0 Q' \( K
, C8 O6 W9 _% O. c9 {6 Y/ k// 这些设备的启用和禁用主要有此函数实现9 v$ X+ ^- P- Q8 r
// 参数说明,nStatus 可取3个值,-1 :啥也不做5 u& s' O$ A2 N
// 0 禁用设备,1启用设备。" Y8 B6 b% j, p7 w/ a
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
2 G; _: q/ }3 b0 \/ G// 也是可取3个值,0 代表软驱,1 代表光驱
: B7 P' ? g% {, K' K; u4 {// 2 代表USB5 p( M1 |2 u; a+ A
// 譬如要对光驱实现禁用,可以这样调用此函数
) g6 G6 A, f. C$ Y" _ Y% @, g// ControlDisk(0, 1);
% U9 C$ j. V7 }3 B7 m) {( K; PBOOL ControlDisk(int nStatus, int nIndex)
: L. \& K" H! M" |' K3 S: N{
6 J+ }1 n7 x( O; u" S; H' D& P! x6 Gif (-1 == nStatus)
z/ s5 Z a3 U6 l. Z{( r% L7 v, q4 k3 e2 W) d
return FALSE;0 M9 A- F9 {8 o" a$ b! A; B. I
}
2 B% U4 n+ j# L; p% p
$ h' p# p9 ]9 m5 {( SLPTSTR lpszMsg = NULL;
: D' T: |( u' Z" f$ e+ Vtry" U% `9 \7 K! @4 e- R: ~9 N% m$ B
{/ J7 l' X5 A' A
TCHAR * GUIDString = NULL;- z1 C. A9 J) s3 C# T; B! ]0 `" o
GUID guid;" n$ A9 {! c% c3 z# @* X
ZeroMemory(&guid, sizeof(GUID));
3 @) Z3 M8 y& k6 |6 B# D switch(nIndex)
/ y# |/ s. ]6 n- |1 l. G% t {; H( E2 Q( l# j6 {4 X4 Y E# P( J
case 0: // 0 代表软驱
$ `9 h4 h$ z% q( o# s( {* J GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");2 G. w) i3 k5 s& |% C
UuidFromString((unsigned char *)GUIDString, &guid);
9 ?$ l0 m& @8 R9 t( K break;
# z C; \6 |4 R4 k case 1: // 1 代表光驱
* [" t) c5 l Q9 O GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");" }2 G6 e+ j, V }9 J7 ~! w
UuidFromString((unsigned char *)GUIDString, &guid);( F7 V2 D2 J$ P1 Z9 `; N" P' t
break;! |# E' o7 a" \+ x6 a1 h% V
case 2: // 2 代表USB
n6 M) l' u& V% Z. Y GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");. m2 S9 o9 Q$ O, e0 I
UuidFromString((unsigned char *)GUIDString, &guid);* I* A& Y# d8 a! N: G
break;& m9 u Q. m9 Q8 A; p- e7 O
}
' s, I0 y, Y1 h \2 R4 O
! Z2 P: k( t+ I0 P" t hDevInfo = SetupDiGetClassDevs(&guid,' ^* \8 o) L: ]: G2 X( [( A
NULL,
( X3 D' M& E1 w NULL,' t$ H1 h; m: }4 Z, C7 a* L! |
DIGCF_PRESENT);
$ S% t; m$ Q0 @' r2 Y' j( R- G4 g if (INVALID_HANDLE_VALUE == hDevInfo)6 M8 R' v( P. E! J/ F' M
{
* W7 e9 u8 r D, x. w9 I" ] FormatMSG(GetLastError(), &lpszMsg);
% Q- s) N5 S; m: o" S throw lpszMsg;; _& [7 C& I* |# l; e6 e8 e$ ^! O
}" _3 N+ b* V5 o0 n' l
. k. U2 ?: R. z# {" V, p. W
DWORD i;
# y* J) Q! g J7 u6 a SP_DEVINFO_DATA DeviceInfoData;! x! P) D4 P& u. A6 h
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
( D; S5 w/ ]) p# U( \4 z DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
' [+ e$ B1 P T' a4 t0 F8 p: D
- r; R" B. y4 v& Q8 t for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)& [8 k) B3 h% ]# Z) I# A- A; w
{. j( {4 O3 Z6 J
if (1 == nStatus)
( {" ^/ a T5 U' |2 c V {7 {. t z, v% Y( `7 g# u- M
StateChange(DICS_ENABLE, i, hDevInfo);
. y7 f. _+ Q0 O0 T! a& I }( }# p# b/ } Z3 g
else if (0 == nStatus)
1 B* I$ Z s5 l { u8 s% r; ~& ] L0 q# O" p% G
StateChange(DICS_DISABLE, i, hDevInfo);
9 B8 ^9 ]! P, G7 c( R( f }
T, |' F6 ]1 M: N' B8 u9 @4 B }, `+ r! E& H n8 y
; C S+ E" o, K, a // 释放 device information set
) a3 R# e5 X) i7 F0 Z return SetupDiDestroyDeviceInfoList(hDevInfo);
5 r# c6 k6 _' [% Z# T! E) R' D# A% s1 p}
$ l" a0 n0 m. k3 _2 ~# X: ecatch (TCHAR * pszError)
. C u, `( G+ [ E{6 C( V" B5 W5 r ] g$ t
::MessageBox(NULL,) C) a( i/ `2 m3 n ]3 p
pszError,
4 P& U! ?7 g; ?+ }# ]2 T _T("提示"),9 A$ P1 F) K% x3 _4 B+ r" N1 l) X4 \
MB_OK);7 O9 ?- M" O2 s% a: c& M3 z2 f
if (NULL != lpszMsg)' R/ `1 C, x8 r# V: U! Y' a7 ^
{- t6 M; m/ u2 F# V1 z; e
LocalFree((HLOCAL)lpszMsg);; [8 q6 e- E" Q
} : S/ Z! o8 U6 k
return FALSE;. S$ X7 U0 `1 S1 E3 c2 W' g/ J
}
5 ?1 t; v4 V! R# i# Qreturn FALSE;
. {2 e3 Z% G T3 y6 \6 j- [}
$ {0 x9 @) G, b: R/ d+ [; N/ C, c2 Q# C o. M @/ `: e4 _
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。: w# A/ _7 g: S
据我观察,在注册表的此项下下:
% l+ v3 |7 p# u! [' } HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\' L, r* y$ o. }# b% y8 H/ |$ u- K
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
6 T6 f5 c/ y4 m+ ]& O! y# @ {36FC9E60-C465-11CF-8056-444553540000}) X0 @$ {' ]5 k9 }; b/ v
这个是CDROM的7 L$ \/ s9 q$ w- z- m9 b. E
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
4 W7 o" a# N" v" r. S7 T这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|