|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)! [! S, L5 q L# _; O6 a/ d
, o1 F! v& U9 E, B; P2 \, g这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
! L% l" ~/ o8 k% X4 ~, N' m// 必要的头文件和要链接的LIB文件
. J* i* `4 W, D) K4 e) |1 x: q( s#include <setupapi.h>) _2 W+ P( X; J$ }; t+ s) T9 d
#include <shlwapi.h>/ _% M/ M6 K/ f
#pragma comment(lib, "setupapi.lib")( x8 Y' [2 n6 x2 v$ N
#pragma comment(lib, "shlwapi.lib")8 p$ N Y' l. U/ m$ z' @
# r9 w1 h" ?: q* }" }// device information set(我把它译为设备信息集)/ \2 x+ ^+ o) \. Y1 `0 P
HDEVINFO hDevInfo = NULL;
& S4 Q2 z( ~: s5 X+ r# { x2 \
# b& p B2 C* K0 G// 出错信息6 w+ j: J' X- M$ G" a, g
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
3 b6 Z+ `2 {" E3 l0 b{ . @2 b6 [' S" O: x: g1 n/ G- a4 B
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
5 o' H" J% N1 I! P# t& d | FORMAT_MESSAGE_ALLOCATE_BUFFER,1 D* A( J, N6 M
NULL,8 V, s, j9 m. k0 J. v+ C! h: m4 n
dwError,: ]2 y; Z+ m O! u, ^. F' S C
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
1 x' S- t- ]0 Y2 J; g (LPTSTR)lpszMsg,
1 v( ~6 j8 b8 C4 s4 T6 l6 ? 0,
# v& d2 n$ S8 W' h* { NULL);
% p9 a% ^3 _* D# Z6 L2 L! T! E& M% w3 N- Z9 Z$ T8 k k+ H! P
if (!bOk)
% E8 X2 R, O, m2 T: z, a2 J3 p{" z- I2 ^/ m8 n5 d6 J& H/ e
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
1 G. A1 ?0 t1 R: | NULL,, S" H; Q3 k3 _% ?% A
DONT_RESOLVE_DLL_REFERENCES);
9 b- f8 }$ k- R) N" d- B if (NULL != hDll)+ @, _. o: k8 b) G" D2 t- c/ J# ~3 J
{
: x- U" y& F/ e8 \ FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
- \$ g, I' C/ ?) _' h8 c/ E t# H6 Q FORMAT_MESSAGE_FROM_SYSTEM,
9 f3 t; l8 v, J* T/ R1 e) {* i2 ~ hDll,
: T0 O) M. w7 R( F9 _ dwError,
! m2 J/ m- {# o' ?0 k% Y MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),7 s$ m% f% C, y
(LPTSTR)lpszMsg,! R( O3 S9 |4 ? i! O8 w1 H
0,4 g8 V+ x C4 ^/ q
NULL);
* T8 F: V: S( S6 [ FreeLibrary(hDll);
6 z) {9 \1 a' n: J8 I/ q }
' q& y5 Z2 x$ Z) D+ r9 V! P/ J}
4 \) i' k! o. p# O' Y} o7 Z$ W: t) g% K! u
, p8 m |% S1 ~5 _BOOL ChangeStatus(DWORD NewStatus,
- j' I8 N; \. y* k5 U5 U1 o DWORD SelectedItem,
8 a8 u4 V0 Y; O/ Q, y0 n1 x1 u) k HDEVINFO hDevInfo)
0 h+ a0 Q6 N; N+ n4 P{
6 k% ~1 |, T F- `- i7 I! E1 kLPTSTR lpszMsg = NULL;
8 C" e; ~% s. ~+ d5 [1 ~- bHCURSOR hCursor = NULL; L( F3 H6 {& g: E, A" e
try
/ C! C3 S Y, m5 {# N) M' W{, t* T2 z E# C5 y
SP_PROPCHANGE_PARAMS PropChangeParams =
; e. a8 A7 C+ J H: L' _, u {sizeof(SP_CLASSINSTALL_HEADER)};
; ~: d; R+ v. U8 D' h2 ] SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
; ~; o$ g/ O. W
7 ]7 J ?4 L. F2 ?% }$ z hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
( Y$ i+ t, r7 Y+ P5 o7 Q$ k- ? O% r/ ]4 D' Z6 a8 Q$ n- ]
// Get a handle to the Selected Item.2 v6 X$ v4 E/ J
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))! p& I0 U! \3 K* k# v
{" q. K E$ J! ^6 l
FormatMSG(GetLastError(), &lpszMsg);
+ s2 K3 S1 s N0 X- R) P9 M) w% ~ throw lpszMsg;
; o( R3 t! Y5 ~0 ^ }
# M9 Y( G# d- O
3 ^3 r- j7 A7 b0 f2 q // Set the PropChangeParams structure.
$ ~1 w4 j* W# ^9 ? I PropChangeParams.ClassInstallHeader.InstallFunction = A8 Q* R& w N. p/ I
DIF_PROPERTYCHANGE;
( N! F) T& K7 f5 x PropChangeParams.Scope = DICS_FLAG_GLOBAL;7 ^0 {, W/ \ T, w
PropChangeParams.StateChange = NewStatus;
+ J, h6 A% f* a5 V4 m! x) u6 U) `2 j* H; l, `. R+ l7 l
if (!SetupDiSetClassInstallParams(hDevInfo,5 E$ q1 X/ d. ^3 Q% m# ~& t
&DeviceInfoData,
# j& x- ]9 b; c) y6 M. I (SP_CLASSINSTALL_HEADER *)& ropChangeParams,
5 H! Y3 A, s2 i. t K! V" N sizeof(PropChangeParams)))2 \2 j a( b: i% |
{ W6 ?. V; u$ D$ l( b
FormatMSG(GetLastError(), &lpszMsg);
q# c+ J! ]5 l, w7 y. c- C% {' z throw lpszMsg;
2 s$ [- o+ U; J& w- @ }' H) O% v# t$ v9 u( Z l7 I
3 w) c1 G$ u' p Y7 k
// Call the ClassInstaller and perform the change.
; H4 C G8 ]$ E7 F4 c2 m if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
; l1 M4 F( }. s% Z hDevInfo,
6 A5 ?- w7 E/ M; j* R$ y1 M' x, F8 O &DeviceInfoData))
8 X6 I- v: G T; x0 z7 }' G4 B {7 I9 W- {5 s* u: t4 q; f( i6 t
FormatMSG(GetLastError(), &lpszMsg);
7 i# K r6 z8 K. p0 ?3 h3 g4 W$ | throw lpszMsg;
: m# m; j6 x7 n" D) h, ?2 l# \7 R }
4 ~' {# r# F' S) \2 T- j! A% j
; Y' d* |0 |- q2 K* f8 J SetCursor(hCursor);
) h. M, e8 r6 S return TRUE;1 W. R; E; Q2 Q4 S# A
}
. g* r- ?+ H: `) C, v# i6 t% {7 w( ?catch (TCHAR * pszError)
}7 q2 n) V+ l$ B{
6 R3 a) ~% r3 G SetCursor(hCursor);
) U! R4 i$ X) ^! r) X ::MessageBox(NULL,
6 v; n" J& X) l- V8 g' J2 ` pszError,' C4 {1 T" ?( `) }6 V- c
_T("提示"),6 L9 C2 u% X/ i( F( I1 A" r* v2 A* x
MB_OK);6 B8 o" b; e( d9 |# ^( U
if (NULL != lpszMsg)
- c) N2 C6 w, c9 u0 m {% y) \+ r' G" ?, ~: W7 l; F+ C3 H
LocalFree((HLOCAL)lpszMsg);3 C0 g7 f2 b' D5 ?- r8 y
}
8 z4 B& t3 A3 v0 D- G# P return FALSE;! I3 W3 X2 M$ ~4 S
} . s0 o) I1 S- _$ R0 T) p8 {9 B! h
}( n/ c, S! K: D- L7 t
w5 z: ]0 n6 p! }$ w
// 这些设备的启用和禁用主要有此函数实现
: f5 d7 X& i1 o' A: X0 i// 参数说明,nStatus 可取3个值,-1 :啥也不做# O+ B/ F: K1 b1 u" |4 C% k
// 0 禁用设备,1启用设备。
7 A, [4 _! j# R* N9 V5 L7 L/ Y$ W// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
; Y+ [" ^* t7 h& C9 A7 J$ e// 也是可取3个值,0 代表软驱,1 代表光驱: }+ r1 X3 f( H5 ?/ G7 ]+ f( D% _
// 2 代表USB
& W5 V$ T/ L' B: K// 譬如要对光驱实现禁用,可以这样调用此函数& D4 _. k+ W2 M4 H
// ControlDisk(0, 1);& C1 o1 j, c9 C0 ]5 o- U. M- [
BOOL ControlDisk(int nStatus, int nIndex)
7 q$ n9 v0 r+ f( i, z{
8 l6 j& m3 ~8 x1 g$ _% \/ Xif (-1 == nStatus)
) [+ u; t7 k1 G$ a{
1 Z* c% w3 V" m( c4 {0 |$ y return FALSE;
! o8 c0 r* w2 [$ {+ s}
% |! u: d* ^* _& z. H: p3 Y3 U/ T" ^0 K
LPTSTR lpszMsg = NULL;% ?* ?) z2 e, t4 s% z9 G
try
; |( Y, S; A, F" ?{, U, D+ Y( Z: G8 ~- ~! w
TCHAR * GUIDString = NULL;
9 x" |' q% {- r- Q! N GUID guid;5 k- f6 X/ _+ G" W
ZeroMemory(&guid, sizeof(GUID));
& ~' ^7 p5 U- J9 ^ switch(nIndex)
6 d, W5 X; `0 f* @' \: g {3 x, }' N) B9 }* V; }/ e
case 0: // 0 代表软驱
5 { R3 P1 F6 y4 s0 Y, x GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");% `7 l9 o# P' F/ Y! y$ ?# @/ y
UuidFromString((unsigned char *)GUIDString, &guid);
* \. u: m$ `6 d break; $ j7 Y" H; q' T8 F! {0 z
case 1: // 1 代表光驱 " Z3 E' W6 U$ W Z2 f
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");- t5 ]2 C0 M" v' }0 c3 {+ o4 }
UuidFromString((unsigned char *)GUIDString, &guid);
2 A9 A5 T9 J" S# c break;
5 G3 F! |% m4 Q# B; N; J4 z( b case 2: // 2 代表USB
) A% \+ P* \2 i+ i GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");6 E' h6 `' M( `
UuidFromString((unsigned char *)GUIDString, &guid);2 F( o! V/ \$ p
break;
9 A- P; J/ g4 J8 p4 ^% Z" g8 ] }- H3 g9 a3 p R5 @1 U; E* L' J
0 c0 b6 p: {) D+ C7 z& \, {( p. v5 ]5 m
hDevInfo = SetupDiGetClassDevs(&guid,
' U$ `. X7 A' g NULL,% c8 j, b* a2 h4 e( l1 a
NULL,
& E% n3 A1 Q, x: J7 ?( M! F1 W4 N E% n DIGCF_PRESENT);
/ C! p5 v2 g5 R, Z8 I& k6 D4 Y' E if (INVALID_HANDLE_VALUE == hDevInfo)) w& d! |5 \9 Q9 f! Z: v7 p' V
{9 V# j L) @( o5 r
FormatMSG(GetLastError(), &lpszMsg);( j9 i4 P0 @. Y* W6 v* `3 _8 Z
throw lpszMsg; O I3 x- }+ A( `9 s, Y3 `
}- J3 c9 q. d6 X, G$ a3 D: ?$ Q9 \
" W* t2 x! e& e; q- m# D
DWORD i;
" Y9 u, J+ X3 k: \6 k' s7 a0 u SP_DEVINFO_DATA DeviceInfoData;, t! s7 F7 C' T, a4 K
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));% p9 T B3 F, s5 r2 J7 ?4 {
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);. ^0 B. b" h, P4 }+ w/ u' Q1 V
, H! U: m1 b6 u) v" b4 |( S
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)8 C& }! |9 T$ L( R
{
& Y: S& H% _( S8 y. } d( K, X if (1 == nStatus)! q; R+ |' h4 X1 G
{* c$ C5 I* s& V9 M- I
StateChange(DICS_ENABLE, i, hDevInfo);
% A s1 f; o. {( m3 P } U* e- J! H M! e0 K7 Q
else if (0 == nStatus)
( W, a9 F. Z, s* j4 x! d6 t {5 l A# }! p+ z/ i, M
StateChange(DICS_DISABLE, i, hDevInfo);# t$ A2 ^& t9 V' X, m) b
} 0 w4 l# V. \8 h6 [- O; N# f
}- T0 c4 R0 k9 F B1 [
$ J2 @9 k/ G( Y F% d) t. X4 o // 释放 device information set
, T# M5 V* M+ b9 W return SetupDiDestroyDeviceInfoList(hDevInfo);
5 o+ [. B1 z [# \}
' Z0 z# X* h w. r# E9 M* ?catch (TCHAR * pszError)% J1 ?' \$ [3 t6 w+ F* a8 _, C
{
5 t0 L+ E9 y S! c" r* x ::MessageBox(NULL,, c k! p" O( s0 D
pszError,
8 @. c8 w; F2 p7 K8 K U _T("提示"),
2 w( E) Y9 `* e MB_OK);
* \# p0 d( ]7 d( x0 e% O5 K! I if (NULL != lpszMsg)
8 A) @5 u8 T+ `0 ?: k {/ c6 ?) n& K: V2 t3 z. v
LocalFree((HLOCAL)lpszMsg);( z8 L, u7 A1 e Z$ \
}
9 Y5 E# W8 r6 _ return FALSE;
% L2 d: n* |8 @# u8 r" ?}
# C: g7 G/ K- P* xreturn FALSE;
8 i7 Z8 D, B( r6 e4 m2 p% ^}1 v( @- C2 ^! `, g- Q( h
% a& Y) _9 X$ S' M' J" F$ v' \) E
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。& b. _" o! r' Q* U, v4 X$ } P3 q
据我观察,在注册表的此项下下:& l: K1 V, V! D7 c
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\, Z3 Y+ ~- E; z5 w. x( x+ v% _, `
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
! t: ^5 g! k \+ i2 V" H s {36FC9E60-C465-11CF-8056-444553540000}
* {$ {1 n: e, d; F# H3 r9 u% L 这个是CDROM的' z9 Q/ F, H6 z
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
6 G! n5 L& y# u6 a这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|