|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)% q' @2 f P$ [
/ t/ c8 m$ ]7 H1 P4 Q5 q6 }0 H这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
% v* {$ f3 R2 Q' s9 d// 必要的头文件和要链接的LIB文件
% p/ j$ m8 q8 A' T. C, Q0 `#include <setupapi.h>2 Z! O/ v2 G, z/ X7 C6 Y
#include <shlwapi.h>
7 A5 N. n* }" t) M4 b1 o' F#pragma comment(lib, "setupapi.lib")4 _! K. J W: p) o
#pragma comment(lib, "shlwapi.lib")6 o5 e. u5 n2 E( N
: |! L/ k& Z9 c, M// device information set(我把它译为设备信息集)
3 `6 u" K8 \# \+ L; pHDEVINFO hDevInfo = NULL;
$ a: o5 L$ A2 h/ _6 c+ v! P+ [# X1 e
// 出错信息
1 w+ v% q' e$ ?: o7 E# q; Bvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)( M; i, k* A; J9 k; j) [, c: J
{
* R7 u+ I7 @- B* V BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
. J& p0 K6 U" a | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ U' S$ F+ k6 r9 L+ \6 a4 b NULL,
- _8 y5 m& I$ Z' M dwError,7 ?2 \( l2 V4 I5 \6 H' D
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
! @) j$ [2 Q' c& f D, L (LPTSTR)lpszMsg,. G: s4 R$ r: r. U& _6 O; p* i
0,+ f% Y2 V6 n5 c( W5 a, L
NULL);: S! F, y$ Z& Y5 |8 K
. V: z' B$ c- O1 g! o1 [8 }
if (!bOk)1 ^: M7 X0 p! L2 b
{
0 D. v* t$ z ~& G, A) V) I HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
; `7 U- V' ^; I p0 K2 a' @ NULL,
+ T5 n7 d4 r( X8 x: P1 G DONT_RESOLVE_DLL_REFERENCES);& q+ G. r ^$ |7 W
if (NULL != hDll)$ E; B' g" e+ Z7 G2 q3 z" G
{" V& B$ {. v$ V! j" F ~! @
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | - H3 C7 B& @/ i8 [; ^
FORMAT_MESSAGE_FROM_SYSTEM,/ [# |8 i& {7 S. A3 ~7 k( Y1 N/ i
hDll,
" H# W) @. _( Q7 E" P- x% l dwError,
4 V8 c# Q% }6 c/ {: j( V: f$ m MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),& [) z# |( ]$ |5 l# a$ ~7 x5 U- Z
(LPTSTR)lpszMsg,3 r, o N G4 M* W) \4 w# |0 @
0,7 Y0 n6 z9 M% [ Y1 }2 `
NULL);6 [0 h6 D- B8 L; A" ?3 \
FreeLibrary(hDll);
4 z+ u5 R6 B0 l7 R1 x: p1 ?2 M2 E }
; R! R, ]8 b" M. l& g$ v, l) V1 o}
" }, l$ [- N* I5 Q9 ~}
% \2 p( \) f& ?+ J. g1 L# m) S
& |4 E! h1 u) d* o* U4 x& rBOOL ChangeStatus(DWORD NewStatus, ' `$ n% v; J" V
DWORD SelectedItem,
& {( @3 g0 v8 ^1 @" C HDEVINFO hDevInfo)( u3 U" v: m6 z5 O6 g) R
{
x7 O) D4 I% j/ G; sLPTSTR lpszMsg = NULL;5 r' A" \( G( P" e _9 [7 t. D# ]
HCURSOR hCursor = NULL;: P r9 Z0 C1 |# j2 @& f
try1 v; c! x0 I( w
{; F) ~( h1 q! C' W; h
SP_PROPCHANGE_PARAMS PropChangeParams =
0 l( j* F! g; ~' X5 l) ] {sizeof(SP_CLASSINSTALL_HEADER)};
! ~/ a- ^5 ?3 v3 v SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; - _! }' ]0 X# N r# _3 C G
/ D5 d# m% S2 e6 K/ W% F0 r
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));# f! @% b6 o* o9 A6 _' G- z; b+ E
% B+ s+ F0 x& b. j // Get a handle to the Selected Item.
: ]+ g c, Y3 t$ p6 R2 D if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
/ {4 _% E$ I0 x {: I" \ h4 @7 q1 V
FormatMSG(GetLastError(), &lpszMsg);6 P" s1 g( f" R* y6 L/ N8 A1 B& z
throw lpszMsg;
/ n( K& v' j: t }3 n. O1 l4 y! H% Q
' m* P) P) m1 l5 ^
// Set the PropChangeParams structure./ ^5 W9 M0 q. o A2 Z* P
PropChangeParams.ClassInstallHeader.InstallFunction = & v2 R+ Y( F" o$ p* d/ S2 ~6 U
DIF_PROPERTYCHANGE;7 x4 w' U0 n; T- z+ Q n7 i/ j. C
PropChangeParams.Scope = DICS_FLAG_GLOBAL; K; X: T+ j6 A. i6 w
PropChangeParams.StateChange = NewStatus;
4 _( r# i+ ]2 G! _# q( p# q# T- L! T# [* j. T
if (!SetupDiSetClassInstallParams(hDevInfo,
( r6 Z f0 }- b; h" z1 B% y &DeviceInfoData,
$ ] C! a: [" j, r5 b (SP_CLASSINSTALL_HEADER *)& ropChangeParams,# E% p; a% ^: D) T
sizeof(PropChangeParams)))
6 f( v$ D9 b# E4 D {( Z7 a6 e: C3 j/ b4 o4 y
FormatMSG(GetLastError(), &lpszMsg);
; V0 m( h# J% w8 Z* X throw lpszMsg;
' d. ^. X6 |) c6 c8 E4 h }3 _/ k+ i6 r, v% L% \
/ x$ F0 Q) M, }# X
// Call the ClassInstaller and perform the change.
7 c: c. n" d, p- U& G4 n( Q5 z if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,' Z# a N6 K4 z4 G b4 u1 U
hDevInfo,
$ l7 \! O! q. C &DeviceInfoData))* n0 _/ X$ P1 T$ z
{
# B9 \) I: H9 f( G* x FormatMSG(GetLastError(), &lpszMsg);
H- A: I- Y$ Z: T# [! e- R- N9 o& l throw lpszMsg;! V* j7 h, F- r
}3 O! k2 j3 T8 I7 s. I
; s$ e* h- h6 h
SetCursor(hCursor);
3 w! p W% f p5 H! U* ] return TRUE;
& [: a1 R& H2 f}* L+ l& b- a+ a% ~/ l; P( }+ N
catch (TCHAR * pszError); r! o, K+ O0 ~% `" T' d
{! d D' g, E* _( \
SetCursor(hCursor);$ i6 o0 g$ X1 |% P$ M( V
::MessageBox(NULL,
6 F- z0 S' v* I# o r5 s' O pszError,
+ V! ]9 l& w; F f5 ^ _T("提示"),
, z) u0 o3 I( f MB_OK);! R3 R1 H* J, ~
if (NULL != lpszMsg)
I* `! X D, r7 x! y! w5 [/ h' d/ e {; s" F2 W3 T. P# @2 K8 q
LocalFree((HLOCAL)lpszMsg);- Q4 B' }( M- @2 E$ a' c
} / o2 ^: ]4 h% ]8 S, G1 a! |: h
return FALSE;$ Q3 y7 ^% d, w% y" J
}
]; h+ g: J- \$ ]; b}$ _5 v; q- H9 k( u; F, M
) E6 S v# c0 g9 l8 |
// 这些设备的启用和禁用主要有此函数实现
5 `5 j0 f$ F) t f8 I9 {& E; {// 参数说明,nStatus 可取3个值,-1 :啥也不做
% Q5 U0 Y- j) z; S8 L// 0 禁用设备,1启用设备。7 \3 Y0 r% `9 C4 _) z
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用! ^7 b1 S7 h1 K
// 也是可取3个值,0 代表软驱,1 代表光驱: V% t3 ?+ @# n3 l( |1 N% |
// 2 代表USB, b* R* g6 J* x6 V! U( C
// 譬如要对光驱实现禁用,可以这样调用此函数6 \& n$ D1 H8 \. x: C6 R
// ControlDisk(0, 1);% O8 ]+ ~4 p- J) A; Z9 J
BOOL ControlDisk(int nStatus, int nIndex)% H: y1 q# Y( A; ~$ Q1 B
{
6 M2 { ^9 y! v! }' bif (-1 == nStatus)6 Z" F7 n3 X5 `' o
{2 i: b8 N+ j4 w. ] {
return FALSE;, v6 L: A' R8 D2 ?/ O3 J
}
8 P' _6 O( _: c7 S8 T! L6 @0 F( e" i; Y; S2 W0 T
LPTSTR lpszMsg = NULL;
0 B7 I8 g+ N: @8 r7 Wtry( s$ T) g- |1 Z2 H4 \6 G4 ?
{
. } k8 |" A* g7 I, } TCHAR * GUIDString = NULL;
5 n& H1 M. j$ y2 K. c# k GUID guid;
2 I- p- Q! k/ B. f* ^5 p6 g$ U3 N, ` ZeroMemory(&guid, sizeof(GUID));
, M) M2 t! r: v$ p# I: T% K switch(nIndex)3 B: Q4 P; D2 V# c. G! N
{! I% b8 I! _+ j% a. \
case 0: // 0 代表软驱
8 K: [+ w2 N4 @6 F' n GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
1 o7 z2 w) c* n3 F+ y/ | UuidFromString((unsigned char *)GUIDString, &guid);8 T0 b% S U4 g+ I2 d3 y
break; # W/ t7 G" r4 B8 G
case 1: // 1 代表光驱 - k. L& b" C7 J9 y; T6 t% V; o
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
$ X0 y) h: @, S! n UuidFromString((unsigned char *)GUIDString, &guid);- G2 P1 I$ L0 Y% c% E
break;" N9 } e. p7 b2 {
case 2: // 2 代表USB
' l4 t3 z& A! V' a! { GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
9 l$ a3 ^; m- K& i9 }3 E UuidFromString((unsigned char *)GUIDString, &guid);2 O/ N1 N8 q+ P( s0 I+ ]* J S' v
break;+ h2 {! y) C9 q1 R
}
( X( u8 x7 |$ X) x" U; y2 Q
+ v8 h2 R0 L' W1 s+ w6 n hDevInfo = SetupDiGetClassDevs(&guid,
3 u$ B$ l1 X2 c/ Z NULL,
" x9 Z- B( B4 ?( w NULL,
0 h) W8 M0 U4 V DIGCF_PRESENT);
7 E: k; l4 r( e- |6 v+ Q' ? if (INVALID_HANDLE_VALUE == hDevInfo)) o" p* G) a* c/ I% ~! c) ~2 d) a+ T7 |
{) r! ?6 s0 D! U% E$ p! i
FormatMSG(GetLastError(), &lpszMsg);/ o1 r; v" P& a, u0 O
throw lpszMsg;( C: u5 E/ K7 g5 y9 t+ v
}' r7 `8 J. {- F( U
( }) y6 U, E8 b% h5 H- K4 ^ DWORD i;
% J0 v0 h0 ?# }* [: D) r. n SP_DEVINFO_DATA DeviceInfoData;
& {3 [) b ~) ` r; t+ n6 K- ~ ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
4 s# p3 |( p/ ^. G9 {; ^ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);- X; c! @! j8 g/ _8 I4 p9 _8 t# S
, s$ x% W2 Z2 L! e! {
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)( T- Q& t' _) S' Q- f) N4 z% ?
{% q6 D8 E8 B; L8 o; m
if (1 == nStatus)
$ J/ r7 R6 v S$ W8 c' Z F {
9 K: U& q4 q% ^- } StateChange(DICS_ENABLE, i, hDevInfo);
9 J3 p1 V3 |" p' P) I5 x3 x }, |) m& A# n/ y# c5 F
else if (0 == nStatus)1 o% \5 S3 I" c% r; h4 {1 v
{- }! e) j& J! O' a& j0 u) f
StateChange(DICS_DISABLE, i, hDevInfo);' s! L" C. c! v1 }
}
3 y9 |8 q3 y! Q }! s/ y; T* p& S0 ~
* I1 @# U, \0 E. L I, _9 ~
// 释放 device information set
' x7 B( S2 L7 _3 p3 d5 V% L return SetupDiDestroyDeviceInfoList(hDevInfo);% h" K: `, E& U" x( I3 R
}# w; Z4 _9 E9 B" o, E; o; m# W
catch (TCHAR * pszError)
0 o0 u2 Y# a) t! K7 f% p{
2 P) L) O- H3 M+ y$ J$ F& S7 C ::MessageBox(NULL,
6 j: o- g; Z' _# J+ y. g2 ^; m pszError,
' P9 j* E% j3 H# M- d _T("提示"),
4 n9 p7 T" B* {* Q% M, N MB_OK);0 y/ I6 j9 e/ K: Y. Q1 f
if (NULL != lpszMsg)0 u% }: B! _! A: J, ?$ s8 n
{
, A4 S* ^/ d! Z& [- x2 J6 r. D% z4 _ LocalFree((HLOCAL)lpszMsg);
# Q' `0 X: D) w4 Z/ p/ V } . d: g5 J$ e$ B
return FALSE;
8 w5 [2 G0 f) h1 F" C; q0 R1 @}. x6 u7 l p1 @5 g4 E3 r
return FALSE;
# f$ _2 ^" H' R2 D) e2 H+ T# ]. I" b}
. k. u" P' a+ z7 A: V5 c% m4 \& p; P# m( H3 _3 b) W, S
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
" c+ T3 X4 e+ N# D- h0 t 据我观察,在注册表的此项下下:
( U0 x' Y) K$ u0 r0 m& e6 w% Q+ X HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
; x5 B" Q' ?% p7 w o- h+ Z 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
$ p- k2 |( c: J5 i0 s2 F7 U8 _ {36FC9E60-C465-11CF-8056-444553540000}# q7 W( z. [2 y: C' q1 m B
这个是CDROM的; t8 n8 Z5 T e0 s
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。7 r( {* f, l* H% E( q
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|