|
(dlutyuanhongl发表于2005-3-15 23:14:04), M% u5 h" G2 }- Q+ \
' W1 j+ |) a$ C
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:% D; w7 D* J7 U, l( T! g
// 必要的头文件和要链接的LIB文件9 I% ], F# Y- F
#include <setupapi.h>! m5 E' b3 o) ?7 m( Z: ?- B
#include <shlwapi.h>0 Z5 S0 X d5 C5 }
#pragma comment(lib, "setupapi.lib")
* v& ^6 z" [1 Q* ~#pragma comment(lib, "shlwapi.lib")" q0 s5 ~1 q3 T; z6 Y) H
9 U) H" [# ?% f& x1 C# Y// device information set(我把它译为设备信息集)
0 f+ S: ?& n# l! J% Z: \2 t; S+ b x, LHDEVINFO hDevInfo = NULL;' U' V% p1 ?9 j- p& G1 `
* M' f$ s) X. C( N/ n) V# M, E
// 出错信息
& @3 D% w' s6 {8 c5 ?' a) Y0 |void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)6 G/ V! Q) Z& G6 g; z" u
{ / J# U1 C- ]0 \
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
# E7 C4 H3 `/ P! F7 E7 V& @ | FORMAT_MESSAGE_ALLOCATE_BUFFER,5 A' i6 n, @0 s. j! f- A1 T- z
NULL,
* l5 f" q+ V U( O6 n dwError,* [& D l9 \; B, x( b* I+ h/ }2 a, {' o
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),: K" \7 Z" `0 _* m8 O' `
(LPTSTR)lpszMsg,6 s! h" J2 S) X* E5 O& S! t; u
0,4 M) ?2 Z% k# b7 A+ `
NULL);5 @# d, X5 U6 {. W p* w2 k9 J
! |# \) K- I2 x+ f8 f6 v
if (!bOk)0 \- D2 n2 D* W
{
" g- A: Z0 ^! y HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),- L) q+ P1 X0 B
NULL,
7 l+ l W( }& O3 j6 W0 z DONT_RESOLVE_DLL_REFERENCES);
! R, p* @9 N$ W$ w4 C0 B% ]! Y% r if (NULL != hDll)9 }+ _- w9 E' n2 ^
{
7 V" o7 F( L, O( t, l7 F- T! z FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
: F% W7 L" U. X" E5 K FORMAT_MESSAGE_FROM_SYSTEM,
; R% r" o- E2 P/ Y- b1 l4 R3 _ hDll,
" a* I4 R% j- M }& { dwError,* A* o, c1 Z, O3 |% z( Q
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),$ C+ V! ~2 l& I ?+ G+ h
(LPTSTR)lpszMsg,
( c' F- K: T/ p6 D 0,
, x3 O* f; t2 [; K& Z' x NULL);! R, c; G6 S3 ?! [0 F. j$ N0 V
FreeLibrary(hDll);
* f* |) w0 F! D }+ q5 A3 L1 Q2 e* w
}7 R0 D4 ^& P7 y- N+ o- T
}
# T C5 Q; {7 W; k& n! k) P+ `, [
BOOL ChangeStatus(DWORD NewStatus,
; E& g3 `2 q4 d& k6 C# |. F3 L DWORD SelectedItem,
6 n- v. V: n+ K0 z# L3 g HDEVINFO hDevInfo)2 Q' ]7 l, V/ C
{0 c y y% D/ ?' _" V
LPTSTR lpszMsg = NULL;4 B, B) S) o3 c) C% O1 ^
HCURSOR hCursor = NULL;
6 d+ r5 _* Z) b/ }6 G& ytry
7 d7 O& l' x. e+ A- N9 I{
( {, D v5 s* J' E& k4 \ SP_PROPCHANGE_PARAMS PropChangeParams =
% x' M& j% U* F3 r {sizeof(SP_CLASSINSTALL_HEADER)}; T$ f. b' [ [$ W; M6 w. e4 d
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
: b8 }8 S) `: }/ L$ |" D. h! R% C# I1 H M- Q$ K* j
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));9 _/ T5 Q, R9 s, k# z) L" a: E, S$ t
! |' N3 d; }3 o+ {+ R+ A
// Get a handle to the Selected Item.9 S$ [2 x# w. P
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))! k- y- q7 M9 K# b
{
/ x' K$ Y; r3 `- ]/ \" L' y FormatMSG(GetLastError(), &lpszMsg);* H& J/ p# @6 q
throw lpszMsg;
: `" D5 R5 H2 c: X/ K% ` }
, Z. ]- t* O' {6 G4 C# T' z( [5 D
" o: j' v" W7 R4 f // Set the PropChangeParams structure.
# _* F( }" U* n# u PropChangeParams.ClassInstallHeader.InstallFunction = ; h/ T* u3 f. f+ G+ y2 f
DIF_PROPERTYCHANGE;
- \3 f/ k8 e* e- O PropChangeParams.Scope = DICS_FLAG_GLOBAL;* ^) V- O& @. y- D1 A0 t- Q2 L
PropChangeParams.StateChange = NewStatus;
: E W) {/ {) m- S3 n- Y+ l6 q8 u3 f9 H5 j9 V; i
if (!SetupDiSetClassInstallParams(hDevInfo,
' I' e5 o0 `: c/ k( B& p2 t &DeviceInfoData,4 c: M: q- S3 P. f2 e4 c; o0 Y& c @; P
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
' l, z$ H1 g8 {; O& U1 J+ [5 h7 ~, s sizeof(PropChangeParams)))( y# w o6 U$ @7 R; M1 i% ^
{
3 M' p5 p" {% M V9 c. m FormatMSG(GetLastError(), &lpszMsg);
% U$ u! ~7 w* S* y* L3 P G! J throw lpszMsg;
6 V' ]( W7 Z4 Z2 j4 ~$ a }- q7 K1 C5 G0 Q8 S' d
/ H: ~8 L; ?6 R
// Call the ClassInstaller and perform the change.1 z0 W- G4 q- Y% O5 d# v
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,' [3 p5 z( a5 {0 `. ^
hDevInfo,, {8 f5 c) m F# l4 Y K- z8 z
&DeviceInfoData))
: @7 [8 }% ]) {. R {% c* y% l( S+ `+ E+ p
FormatMSG(GetLastError(), &lpszMsg);. e! \% A# k: ^" [/ V1 }; W
throw lpszMsg;
2 u" H! ^& |: Z+ n }
( ~" j' H' o0 q4 Y2 @
; Z+ e; V' p# Y4 |* ^ SetCursor(hCursor);
, |& p6 H1 q2 c! j return TRUE;; X: J( ^1 p5 `5 S6 |, f2 k; F0 ^( A
}
* g- C* w; m: g/ p6 V+ L8 V6 gcatch (TCHAR * pszError): n. }* n( h5 h' ], y4 G; |: W
{3 ?( Q6 Y/ F& d) s
SetCursor(hCursor);0 M1 r: X$ m4 B; [7 z0 ^
::MessageBox(NULL,
2 C. ^/ b$ g$ M1 q+ d; o$ o+ ] pszError,4 Q4 T# Y& W- x3 O8 @& t
_T("提示"),
% o3 }, K9 @- W- C. X MB_OK);
. X) {+ Q4 D" A6 H9 ?4 y( L if (NULL != lpszMsg)! b" y( D) i8 |
{; o4 S {3 `0 M
LocalFree((HLOCAL)lpszMsg);
, m3 p/ k/ \1 @. O }
9 @0 a; L _6 P& U3 ] return FALSE;
: ]; C/ }: p1 c3 a* H}
* V' {, S1 ~& ^1 l0 B, d% o}
7 P) ~. i5 I4 d) B& V. a
/ s# b! |7 `" e% A- y// 这些设备的启用和禁用主要有此函数实现0 _! O2 M& V1 k5 {( V
// 参数说明,nStatus 可取3个值,-1 :啥也不做- n' r: ^ D% B) Y/ I
// 0 禁用设备,1启用设备。
% c6 H' T6 ]4 y, u% |9 H// nIndex用于控制是对光驱,软驱还是对USB启用或禁用6 p& V5 b/ b7 E9 j' F- Y
// 也是可取3个值,0 代表软驱,1 代表光驱
. M- y+ I& j5 X- a// 2 代表USB
+ d, s: p1 j2 w/ ?" m7 m8 d8 c// 譬如要对光驱实现禁用,可以这样调用此函数
+ r9 S; Z( M4 Q2 V ^// ControlDisk(0, 1);0 \0 d9 u" ^# D( G! W
BOOL ControlDisk(int nStatus, int nIndex)8 o$ w1 n# w* ^2 u5 y# n8 C. r
{( F1 H; o+ G7 g$ X# l; ~; q
if (-1 == nStatus)8 Y7 Q8 A/ V4 c6 I6 x2 N
{
1 Z$ m( j! j# m8 L/ _6 N" b return FALSE;
5 \ I( ?+ R, V2 V0 i; G+ Q}
# u8 D: d) E5 i% E( h/ P! ?
3 b1 i: k! k; H: r9 {) ELPTSTR lpszMsg = NULL;
1 F! l2 J/ G2 V4 m. j. E) }7 qtry
6 J* y( j. i. ^ ]) o0 i{
( K/ F; f7 B7 I9 D& L) u* x TCHAR * GUIDString = NULL;4 z: f. r6 u# F. x3 v9 Z& A9 M
GUID guid;$ t$ r; P# _) }8 a: [( t
ZeroMemory(&guid, sizeof(GUID));
9 P5 P1 w( z$ C" J' b switch(nIndex). q5 W v& B5 L% n0 \) L3 y
{6 E' C: t" v) X( v; ~( B; d9 W
case 0: // 0 代表软驱
. \6 \: ^% m' ]; P0 } GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
1 a* T$ s% W2 }5 f; Q; q8 z3 a UuidFromString((unsigned char *)GUIDString, &guid);$ `/ S6 x2 ]+ W, c: Y' x6 W
break; 9 q+ V4 g- b/ G% S ?" w
case 1: // 1 代表光驱
~( P# w8 w) e GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");) P7 W2 p' `3 Z: X8 K: M, T. L1 G
UuidFromString((unsigned char *)GUIDString, &guid);. S1 Z8 u, t5 s# W* |, u0 ~* p* D
break;/ C3 ^0 V: G# Y& P5 h, I) H/ C' K
case 2: // 2 代表USB A* {. |8 i6 w/ y; Y
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
w2 e, w1 C" z. E+ w3 ?( y+ I UuidFromString((unsigned char *)GUIDString, &guid);
. {- m2 L0 x0 O, I2 x6 p" u3 X break;
. N- C2 f/ y+ Z* }+ e; {& y }
7 m( a0 @2 m( z4 `% T5 V! h
/ N: j1 g( o1 \, z1 A B hDevInfo = SetupDiGetClassDevs(&guid,. ~+ z$ p; O6 k9 H* l
NULL,3 E y% e0 a. h' n- u" w8 b9 U
NULL,6 [1 a) h) }# _5 F% v! T, z
DIGCF_PRESENT);
( B+ ?) k# ]2 D* v1 L if (INVALID_HANDLE_VALUE == hDevInfo)
5 C) g2 t% X1 T8 T+ g/ m' H8 A {( }" b0 P* I( s, E/ Y
FormatMSG(GetLastError(), &lpszMsg);+ V, h. ?" H8 k$ H9 Q
throw lpszMsg;. O( D: N+ C3 x
}
7 a8 U! `" a8 N: V: T4 A
" K" ~! d8 d* t4 r6 ~8 j2 U6 p DWORD i;
0 \7 D: _& i$ z* p# }6 C7 q SP_DEVINFO_DATA DeviceInfoData; p# n) g4 @7 H
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
2 u3 Y: t& }* l DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
! \& h. Y0 X' x9 W% }
" h3 B& d! h! ?" A" { for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i), ~5 S2 _- v- _9 q9 v3 h* ^7 r$ l' w% \
{
$ U# q$ O+ h7 f1 R: o/ F if (1 == nStatus)
1 B9 c& @* w# d4 l { E0 M4 o8 o" b! d
StateChange(DICS_ENABLE, i, hDevInfo);7 M9 c/ j( k( [
}, S4 U5 q B2 a" z0 ^+ ^
else if (0 == nStatus)$ q W+ y% _9 R: f& _6 m$ ^$ e
{5 |: c Z8 k9 h9 x5 {6 z7 D9 L: d
StateChange(DICS_DISABLE, i, hDevInfo);6 c3 C! C2 B) n* {# {+ b# @
} " i* t9 j( q) I$ _- N0 h# K2 A, C3 x
}" n Q$ }9 K- Y9 z, I
& K J9 V7 w0 X // 释放 device information set
* W" q! P$ h( G$ T$ F3 e return SetupDiDestroyDeviceInfoList(hDevInfo);
# N2 n! [* p: u: w" R; I2 U$ y}( q! e9 g, e+ G% i# e4 d
catch (TCHAR * pszError)3 J2 k. G( W5 A9 P
{
T7 Z" r; b7 y, C ::MessageBox(NULL,: a) l) `4 J" K8 j1 f% ~- V
pszError,) k% c. X# g/ i+ ~
_T("提示"),
/ W4 G: h" J7 `0 b) q MB_OK);/ F" ]: q7 H9 K
if (NULL != lpszMsg)
# [7 i# k/ J! ]/ R8 Q! U0 I {
; A, I& l( {+ _% m# \ LocalFree((HLOCAL)lpszMsg);
; @9 C8 a" t1 l) \& V: L. w } 4 w) V* [9 I" Z* }% y, d
return FALSE;! D, `6 C8 J( {2 k% W5 Q
}
" E! j/ E! r7 ]- hreturn FALSE;% {8 Q1 o& x- O; M0 b
}) q8 ^7 q2 r' ?/ A1 ~! T
9 v" y+ [9 a% I* W* u5 o
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
+ y" m y9 k( C( q* k3 M" E4 X 据我观察,在注册表的此项下下:
- }; H8 x# n" I7 \. a% N4 f HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
5 \* f. w! F/ j& D f* g 有很多GUID,每个GUID代表一个设备,譬如这个是USB的" V5 e9 F7 P! a2 K9 u" N2 x! r
{36FC9E60-C465-11CF-8056-444553540000}
t$ W4 w( L6 p 这个是CDROM的
4 ]9 G! d/ L& I! o, Y; l4 o {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。) C" r3 y( v0 m f
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|