|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)* w9 o# c8 o- v, @
; I" W) g5 d9 b( f$ \0 b; s这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
& S5 }1 x. v9 [- W) p) Y. r# M/ U2 M// 必要的头文件和要链接的LIB文件
: ~/ A# ~2 c- c4 T: B2 Y z#include <setupapi.h>% ]% B" N6 }( `/ i# ^1 }# i! l
#include <shlwapi.h>
1 J* X0 r0 E; j. q5 r6 N k4 u#pragma comment(lib, "setupapi.lib")
w9 K$ A& O& G; e#pragma comment(lib, "shlwapi.lib")
- J2 s! q: b/ z2 t: C( y( u9 O% E5 G* z5 x9 ^
// device information set(我把它译为设备信息集): |, o' P( n, p& B# W
HDEVINFO hDevInfo = NULL;+ C; C. B% r7 M: z
# |9 v: l: F' \5 Z$ o4 L// 出错信息4 ]) o3 c% ]2 Q7 }+ S! E" N4 c
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)1 a0 X) ~$ j* _
{
7 e3 G; X$ Y D5 t5 t) B* ]. F2 G BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
z7 h9 ]+ Z9 n: T1 e. @) P | FORMAT_MESSAGE_ALLOCATE_BUFFER,
( ?9 u2 N% u0 x* N, U; \ NULL,
4 R: |3 b1 e) H" Z dwError,
, M. @( C9 H& [) r8 X1 ~8 ^ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),* U4 d$ p5 u' O- k* F
(LPTSTR)lpszMsg,% x1 K9 l' g% @
0,
* G, D/ ^; m$ H) y' I$ p NULL);
& }) B+ _& D: |$ @6 h" v5 v; [0 Z2 h3 g3 b, F# N5 U
if (!bOk), L3 _* N& {! _- F
{
; o1 ]# U. t$ k+ W" x( m" T% P7 | HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
& _2 \$ Z, U. p, \. s0 I+ k NULL,
' C* ]1 l) v( v( F7 i DONT_RESOLVE_DLL_REFERENCES);% E1 C% e' Y5 u( ~
if (NULL != hDll)- @/ b3 R1 n/ T3 f# l
{5 ]+ d5 Y5 m% M' X
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
3 M V$ P" o% S |: i FORMAT_MESSAGE_FROM_SYSTEM," }" m9 x6 r/ L( U( [. f
hDll,6 @; G0 L. e7 v* ~( U# y0 c) S
dwError,& A7 C3 V* b2 K3 \/ n" k0 a% O
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
9 I ^( B6 ~1 t! `- Z (LPTSTR)lpszMsg,
; q& C6 \$ M9 I8 k 0,
# T: [) \3 G' Y# `% @ NULL);
9 U1 i% a$ [) e: o0 t- i: V FreeLibrary(hDll);, ^5 r) ^ b4 p2 e4 ~) M
}
: f3 p" L! @6 N8 G" S% l2 H}
) o3 I; w6 [1 l2 `}* ^2 f' ~4 ~; {2 w& Q& L. C
! S' g) ]; C& e, ]
BOOL ChangeStatus(DWORD NewStatus, % u2 d$ ?" r+ U
DWORD SelectedItem,
; o% b) r+ V5 K* h2 X; i3 Y; {* b HDEVINFO hDevInfo)- {3 t4 x) F Y; C" A* y% e
{
8 x* r9 ] I3 o( f( `3 t0 VLPTSTR lpszMsg = NULL;2 V+ y7 b- w$ k, P
HCURSOR hCursor = NULL;
. V6 J7 l( B7 b" w2 p4 |/ ttry
$ N7 q& Y2 f: Q3 e; c. c{) N% J. t/ i/ X$ F1 ?: J
SP_PROPCHANGE_PARAMS PropChangeParams = ( e: A+ J2 `8 T6 `6 w. U
{sizeof(SP_CLASSINSTALL_HEADER)};+ D, T- i0 F/ i- V6 i" I8 M6 D6 K
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
/ j' O2 }, e# I, D6 A" C( z
- H4 l/ B S/ D6 H2 s hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));) G0 Q+ V4 M! l% o9 w* o
' M- u$ Z3 \- v" C/ W' x# j
// Get a handle to the Selected Item.
1 |9 X% z2 d9 q- `6 K if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData)) k/ {) z% f9 K( |/ t" d# D
{
; G c9 ?9 }# `+ j/ m+ [* x FormatMSG(GetLastError(), &lpszMsg);0 Z6 ^8 T. V. W# z
throw lpszMsg;
4 H" d5 V' h( e& A- @3 A4 ~ }3 J. d2 M. X5 W! v, Q% J
! L; o( H/ j% Z: v$ v# _( n // Set the PropChangeParams structure.5 [" t8 k) G* V" w) {/ [
PropChangeParams.ClassInstallHeader.InstallFunction =
/ b6 l5 ?! d f. F) p* \& W DIF_PROPERTYCHANGE;
) m7 A P9 L/ t% z4 {& V) P PropChangeParams.Scope = DICS_FLAG_GLOBAL;
1 l3 O8 l! L2 f! U PropChangeParams.StateChange = NewStatus;
' h3 |- s* e$ ^: G9 M
$ d' v; V7 l5 H+ N if (!SetupDiSetClassInstallParams(hDevInfo,
( P" i4 v% t W/ s1 }3 a" h# x &DeviceInfoData,
8 m# `& _ {% h: O0 B/ ` (SP_CLASSINSTALL_HEADER *)& ropChangeParams,4 J/ S2 m' x. @: Z4 V6 W/ L
sizeof(PropChangeParams))), F- X& w1 Y: D0 A+ p9 `
{# j% h7 S& Z" `9 I4 Z% d
FormatMSG(GetLastError(), &lpszMsg);
[$ i& ~0 F2 R+ b. ~: K throw lpszMsg;
. G R" A1 Y, _4 |9 C }
p! m& _7 Z" ]: `, q
) s" g: e" I# Q4 R // Call the ClassInstaller and perform the change.6 Z9 t2 K$ }7 H2 r6 u
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
& f W3 D3 A/ i8 G% j( Y+ B hDevInfo,/ w3 B6 x7 A+ Q9 v9 I( o
&DeviceInfoData)). c9 s, e, N& }5 ~ P6 K1 f
{3 V9 Z! R ?& z
FormatMSG(GetLastError(), &lpszMsg);
! e; |) V p; X8 d throw lpszMsg;& O9 W% Z- _4 J; ?
}
7 ?+ G/ p, M3 L- d7 b7 B; T" ?
' F. S" P9 n/ A1 j SetCursor(hCursor);
Y7 s, g3 A- X return TRUE;* [4 L6 d( S" ^6 Q2 i
}
8 c6 X; w$ u4 ~' D7 }catch (TCHAR * pszError)
( O* U- p& ~0 W1 ~( B{
6 D: Y" ` U/ v$ Y# P SetCursor(hCursor); A' r( x% r. g& u5 G
::MessageBox(NULL,4 Y2 Z x7 J: g/ E& T
pszError,. Y0 H8 D9 o4 N
_T("提示"),
' @; p: M/ @* l! q# [ MB_OK);
3 y; `! V! `- t if (NULL != lpszMsg)$ ?' k0 K* r! Y0 [1 P
{( J+ V: y+ t0 S/ O
LocalFree((HLOCAL)lpszMsg);
3 v; g3 }3 P7 O8 B7 s$ |2 Z }
; e! ~, _1 M: x: s) X/ O X return FALSE; X$ z% b# u; D! b$ t0 U( @! [; y) Q
}
' j D# @* J% b a8 u}
2 n! O$ r9 ]: T2 a' q0 q( Z8 f
0 J0 \3 u+ R$ v% ^' ^4 Q9 o8 u// 这些设备的启用和禁用主要有此函数实现7 x6 u$ v B' I1 K) ]5 I1 P
// 参数说明,nStatus 可取3个值,-1 :啥也不做
, s' R; f3 R/ A7 F0 l: [// 0 禁用设备,1启用设备。
6 E! _4 a4 U, Y8 N// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
u( {( b/ t& E+ x; ?// 也是可取3个值,0 代表软驱,1 代表光驱
7 O1 F4 J- k2 O9 H: Y$ j// 2 代表USB
6 ?' t5 P+ N- o% y// 譬如要对光驱实现禁用,可以这样调用此函数
) z9 Q" J9 T5 c/ Y- G/ T// ControlDisk(0, 1);
+ h V3 o4 p) H- zBOOL ControlDisk(int nStatus, int nIndex)
4 |5 B2 q, k5 i( i. D) ]5 {: h{
! Y- r+ W$ _4 q: E/ G& Kif (-1 == nStatus)
( i4 c& a0 r. ?; A8 @2 {{
4 s3 I: t7 ? q$ c8 c return FALSE;
2 H' Y, a% T9 y: F9 ]+ a}
; O& ]: g' A0 O. l) ~+ ]$ O' Y' A1 F) c2 ^9 K
LPTSTR lpszMsg = NULL;
& E$ ~: j+ L; d5 W }$ ^try8 e7 w$ ~/ U9 k0 @3 z
{( Y! j4 W3 Q7 s1 y. J6 M
TCHAR * GUIDString = NULL;+ F8 V2 f: M8 y0 Z, @9 |0 N
GUID guid;
: a; l" p: e4 \+ k' ?' |7 Q5 B6 O ZeroMemory(&guid, sizeof(GUID));
% A4 r h8 ?+ T0 c4 c. l switch(nIndex)
3 E! ?8 r5 L% k% M9 Z7 t {* e4 X* a/ N, H6 J/ _6 m: I
case 0: // 0 代表软驱
7 o1 L, U9 X6 K GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
& w* ~9 \( r* n/ p! T UuidFromString((unsigned char *)GUIDString, &guid);
- e- I1 \) g$ o) \7 Z break; 8 F# v2 g$ K8 U& k
case 1: // 1 代表光驱
+ _) a( t4 B$ ]; A4 f3 F- P GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");9 e2 g6 Z1 p' ^8 D: I
UuidFromString((unsigned char *)GUIDString, &guid);
8 U# F0 q" [6 G9 D' R. L" L0 h0 _ break;
0 a9 N8 D: X' m- ]- s; }* P8 N! \) p! c case 2: // 2 代表USB# D/ r; G. ~5 e$ s* w! @
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");- m1 e- F% x- y% M N
UuidFromString((unsigned char *)GUIDString, &guid);
- C, y0 P) S0 @* b d8 Q: C break;
5 p0 n3 `3 _9 }1 g }
2 q. Z- W7 Y/ y4 w/ S
; L, E# `4 L1 x2 W hDevInfo = SetupDiGetClassDevs(&guid,
3 f& N- `2 H: f; L f8 H0 O NULL,
0 E- }" u0 q; v$ ^ NULL,: v' A) I$ P# t6 j3 g& p
DIGCF_PRESENT);0 v/ h5 s! J l* x
if (INVALID_HANDLE_VALUE == hDevInfo)
, O7 f, j: ]1 c t9 U- ~. Q* m# O {% \7 A8 R9 c& b+ k4 D! @3 a
FormatMSG(GetLastError(), &lpszMsg);
9 U) e+ s8 ], k throw lpszMsg;" c/ Z1 b+ Z+ L1 s2 m
}' w2 k: X9 F T0 A$ G2 T
' c1 Y; {7 c, I# j
DWORD i;
$ o& s3 `2 ]5 G0 |" o; P4 i' C SP_DEVINFO_DATA DeviceInfoData;
" n# P8 I1 b, c6 l% _5 f ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
; V% `- q. O! M$ { DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
. o5 s/ _2 y- D0 u. t+ z" a! Z: H% J. p6 ]. i+ W
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)& V: a4 R9 o: i
{
- q$ x5 _5 X& ^0 C if (1 == nStatus)0 _$ ^7 a' G" |/ F0 n5 r% ~
{: |7 \% H+ a% j7 \2 F: J
StateChange(DICS_ENABLE, i, hDevInfo);
) V/ y3 l+ q& Q7 h; E+ ? }& F% e" ^, f6 H; q/ E
else if (0 == nStatus)7 T2 W' E1 O! H: r. i
{
" H& X+ U% m9 w( Y, l2 Z# \ A; j StateChange(DICS_DISABLE, i, hDevInfo);( l+ O3 G/ p# j! K' v
}
2 H8 Z4 q: T' j5 B8 W' d }# N" k7 e8 @' c6 [0 d! i3 ~% V
8 T$ ]& n9 ~+ l/ H
// 释放 device information set, R% J/ J' I9 m& e
return SetupDiDestroyDeviceInfoList(hDevInfo);
, i- B& }* A" P8 u}/ \( [5 b" f Y7 ?
catch (TCHAR * pszError)" A; w+ T! a8 ~0 E2 R
{
5 E" h' g5 P0 Q ::MessageBox(NULL,
3 l$ Z _, z+ x$ F8 V8 W1 t pszError,
' Q8 n4 q& i/ j" p2 Q3 k/ | _T("提示"),
) q. \. b* K* q+ y+ o/ |# P7 D MB_OK);7 ^- z3 r- d9 M8 w
if (NULL != lpszMsg)& S1 u4 z1 K- t) I
{
- F0 D; w4 u# R LocalFree((HLOCAL)lpszMsg);
. i" q8 z, t h }
; h6 O+ X. I W; y4 u return FALSE;
# j5 @" x+ J$ \+ k6 k}
1 ]3 I, B( a5 a t8 U/ f7 P6 I, jreturn FALSE;
( `4 l6 L( ]% a' p3 [. }, N% N}
8 y+ b" N0 u+ A) G* w; Q9 d. D( D
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。+ W5 Y1 P. {4 {( Y
据我观察,在注册表的此项下下:' n$ |6 K, c0 ~' d, _( m# a0 p
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\3 h7 j) w/ w, g; M/ `
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
# r' c8 O0 ^+ Z4 k {36FC9E60-C465-11CF-8056-444553540000}, Z( K! O; ?' m$ G
这个是CDROM的
9 i# s. p% k. o& E {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。1 b6 ^& e: m- T% {, X. ~
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|