|
(dlutyuanhongl发表于2005-3-15 23:14:04)4 O$ J( O5 t# i1 S2 e
! P1 B& R+ J9 m) d$ d' F/ A2 u9 r
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
8 y( l3 K2 e9 u1 \. I; M// 必要的头文件和要链接的LIB文件
$ ~. E1 }: d) ^, d, L0 j#include <setupapi.h>
/ o5 n: f$ w) \; G1 \% ~#include <shlwapi.h>: S3 ^1 n6 y5 k$ n1 |; @
#pragma comment(lib, "setupapi.lib")
5 |* W/ j* t; @. j#pragma comment(lib, "shlwapi.lib")
, f. d. T7 o5 i4 W9 J- r [6 `4 K/ m% M- M+ x- n
// device information set(我把它译为设备信息集)3 q- ~& U1 l. N
HDEVINFO hDevInfo = NULL;
+ J2 ^6 z, ~; [1 d; P8 A9 v! V0 e, C& |( {
// 出错信息) e& U3 V8 Q& X6 J' Q: R f
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)' s6 g6 n/ q/ [3 Y
{ # a2 e' [3 L3 [3 E: ^5 Y
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM & r; i' |2 c4 C7 K* J
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
# Q9 b6 S& L: Y: P NULL,( B5 o W" a; z( \, Z( T* A3 J5 _
dwError,0 y) c( ^# \& b$ B
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
9 ?4 ?7 D9 F5 v! v; R. ^ (LPTSTR)lpszMsg,
9 h( c& ]" D3 w3 k( w 0,
5 w" }7 a( ?2 D5 _# J- w% T3 ] NULL);9 K. y' t ^0 T# b [
6 s' Z% T+ K4 e0 z% J" ]2 cif (!bOk)
, G F; a3 j* N{9 p5 `0 G9 p) V. c+ x2 b, Z! G
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
, O3 W6 D3 Z2 M NULL,
* i9 `# v! s. v DONT_RESOLVE_DLL_REFERENCES);& x4 v- W1 I" l) T
if (NULL != hDll)- o2 Z; u' ]& }+ g7 k# [. \$ k
{
7 z! K. _4 ?) M) [3 R FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
, v/ m* t# Q/ x# b FORMAT_MESSAGE_FROM_SYSTEM,
, b l0 c5 Y8 s4 h6 U& k# T z hDll,
) e& o e% i. i& z" R dwError,) e4 f7 z2 i% D3 v; }& Q
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),5 i |* m& N5 B+ w
(LPTSTR)lpszMsg,+ d8 L o: R+ m& D) s, u7 t
0, f+ l# N4 u0 L: l- ]# @
NULL);
$ R" I, N) [$ H6 M+ e FreeLibrary(hDll);
@1 \7 L/ J3 \6 z! B( k9 G: e }0 Q+ q8 z. _3 ]& ~* U, _
}4 h6 D2 J9 Z( W& |- [
}
1 F8 {7 g- o! G
9 X; I2 y% D( s+ f _BOOL ChangeStatus(DWORD NewStatus,
. B6 h7 O* k, y DWORD SelectedItem,
% V+ N7 k0 `% P0 q }4 e HDEVINFO hDevInfo)
! A( G5 B! W J. z- ^, A{
# s. N( L! U4 o: w9 A. T: RLPTSTR lpszMsg = NULL;
5 |8 M. q/ H) y0 H1 LHCURSOR hCursor = NULL;
# r4 S0 D, f" X( htry2 y1 B$ m: @5 b" h
{
& \" B; v, B) y* o' @# l$ U' O L SP_PROPCHANGE_PARAMS PropChangeParams = * ]' ]! u" @ i* L, n+ O
{sizeof(SP_CLASSINSTALL_HEADER)};6 N% p1 c) \8 z9 T9 n
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
! w2 E) q: U U9 d: _! k* o$ @6 T2 n: [
2 W3 v$ _4 T; P& o hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
! K5 h7 B' y2 x/ _1 Q$ H$ B4 j; y; y/ I1 ? K
// Get a handle to the Selected Item.
1 ?1 o% h5 \; I6 | if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))3 b5 x: Z2 n2 E/ H t
{
# e4 K' o: B7 g9 e FormatMSG(GetLastError(), &lpszMsg);
+ ?3 j: c' X, {1 S- ?% N throw lpszMsg;
: T# j) z* I# e$ }" S- w }9 J/ B8 k" z) q2 C- Y- F. Y' M
( d6 ~7 L8 \; P M- m // Set the PropChangeParams structure.+ t0 C/ ^, u3 U+ Z# m4 h
PropChangeParams.ClassInstallHeader.InstallFunction = 1 Z1 ^. ~) ~2 A, _3 B7 a1 \
DIF_PROPERTYCHANGE;; K; h9 Z% |4 G* D" m' H
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
1 G- R+ D* f( ?, m9 W% I! O PropChangeParams.StateChange = NewStatus;( G- t7 G H. R$ @
+ C( z, ]; }( A% ?% R& I6 x if (!SetupDiSetClassInstallParams(hDevInfo,
, {, | I/ U; O4 j &DeviceInfoData,
8 a% i; a. V+ l' |& c, y M (SP_CLASSINSTALL_HEADER *)& ropChangeParams,6 T8 y/ X: z D" A
sizeof(PropChangeParams))). a D8 K/ n4 h9 h# `, ]: i" |, _
{
# B' Z% J' K# S+ L3 i& J- ?, U4 v) g FormatMSG(GetLastError(), &lpszMsg);
; D2 x* A6 b( V7 d' O3 Y }9 j throw lpszMsg;
, a( o& m* f5 G0 l" V( D }
4 i+ _8 ~ w/ R9 g$ E" W: b: s+ _
// Call the ClassInstaller and perform the change.; T, S# L: Y V. i% v
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,# c) `: \, s- }6 X
hDevInfo,
$ u' L$ b$ i, K, E &DeviceInfoData))
8 q) z% ?0 F; A1 j* |9 T" c [4 X {
4 c; R. t, V' o1 y+ j! A FormatMSG(GetLastError(), &lpszMsg);
' q3 Z& C8 n7 b1 y3 M( c throw lpszMsg;
6 p9 ]: {2 A- R: U' m- D& j/ c }
) G# M5 Y9 g4 [% E& Z/ v& U" p6 I) y
SetCursor(hCursor); ' H/ C6 H e% K" m& t
return TRUE;
4 y. S3 p. [- j- d}
) [5 c g1 f5 H! W) M; N/ bcatch (TCHAR * pszError)- S* B A- X- m, o* c1 Q; o
{* o: _; _0 J6 A8 t f3 b
SetCursor(hCursor);
2 w# a; [3 A+ {2 r* }, F ::MessageBox(NULL,' f5 @- L: M; K% M6 ]7 ^
pszError,6 j. K3 \! q. v$ z
_T("提示"),0 g+ u; s& s" p) P
MB_OK);% X" ]* Y- V8 g6 i- l
if (NULL != lpszMsg)# W' F/ x) C$ V+ a/ V2 \( i
{$ p* U( T1 X) H2 x4 y
LocalFree((HLOCAL)lpszMsg);
# O6 f; _; g! v; B9 U/ `$ p }
# h4 C, q# {5 Z* r+ \+ T( ? return FALSE;( A) _# \+ z) D2 c; ~' N0 `
}
2 U( \% y) W) M' h; A, J( w! N}) [* q! L% I" r4 F* v7 q
5 x0 t, s1 J2 P9 r6 l" y% T
// 这些设备的启用和禁用主要有此函数实现
6 A6 m' x: y* S: U r" j# U// 参数说明,nStatus 可取3个值,-1 :啥也不做
0 A, r* u5 M7 S& H// 0 禁用设备,1启用设备。. p" a0 ~- M6 k& m: _0 S
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
2 t+ R: g3 ?% m4 z. O6 o3 n// 也是可取3个值,0 代表软驱,1 代表光驱
, ]* C5 D4 ^; V$ \// 2 代表USB
U3 @+ \1 T* Z: ^% L+ Y2 I* |1 y }# Y// 譬如要对光驱实现禁用,可以这样调用此函数0 }& f" H" m. J i! v3 F" ]4 `: t
// ControlDisk(0, 1);
( B& k) I7 e7 GBOOL ControlDisk(int nStatus, int nIndex)
+ j4 H. ~! I: w{. P- M5 O T- F& a0 g5 N# H) S
if (-1 == nStatus)- s1 Z4 i7 H/ {& ^2 ]
{/ }% K6 V/ i. C% }% z% H
return FALSE;
2 d( { w9 q+ E. l3 G} * y2 k" T2 k8 }% _9 v
% l; j. x# E6 ?# H& z1 L0 ~
LPTSTR lpszMsg = NULL;
! B2 P" S& v) |" C+ w* ktry
5 V& A3 l5 t ^! X{3 s2 \0 N& [: i4 _% x' u
TCHAR * GUIDString = NULL;. J: L/ ]( m5 t2 t* Q
GUID guid;
) ^1 Z r+ }) `6 B# p: a% {$ V ZeroMemory(&guid, sizeof(GUID));
3 y/ n2 b) t( V# l( r' J$ T switch(nIndex)
9 n0 s6 v: u5 [0 ~! E2 D% z: ^* y {
! }: ]$ K" Z1 s8 Z/ c& ], v/ J( I. Z case 0: // 0 代表软驱' P: c! H9 d# Z+ f
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");0 j! {: ^: K2 i* L7 ~: g. n0 y7 I
UuidFromString((unsigned char *)GUIDString, &guid); A. T' ]! p1 }4 J! C4 Y- A8 J9 c
break;
" P1 v' b' m& N% }3 J& ]7 ] case 1: // 1 代表光驱 0 z: W1 w1 L' d/ R' l7 L7 `
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");" A ~0 n; W( \1 \6 P
UuidFromString((unsigned char *)GUIDString, &guid);
3 F, m z: w, m' X break;' l/ B% y5 G# O
case 2: // 2 代表USB+ c4 \3 l2 o/ y0 p! M
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");! `! w5 _9 Q, G; J
UuidFromString((unsigned char *)GUIDString, &guid);
. J$ Y+ E! h2 t) @$ P break;
- f3 h( U' R9 Z }& b: q' O& L; ?* r4 h! r
9 _! _) {2 F: l1 B$ R- u
hDevInfo = SetupDiGetClassDevs(&guid,- B! M, B. ]+ h7 y/ s
NULL,
8 \2 t0 i u) Q5 g4 K; E NULL,
7 J* y# X9 L; q7 I DIGCF_PRESENT);( N$ Q$ Q+ k; P2 [9 ^& B( P
if (INVALID_HANDLE_VALUE == hDevInfo)
7 C$ m1 b5 p/ S2 p2 l1 S) Y- G; J/ B {
# ?' ^- X% N/ v/ k$ B7 c/ P FormatMSG(GetLastError(), &lpszMsg);
; c: f2 g2 q6 ], T3 y* Y throw lpszMsg;" ~( Q5 _) f/ h5 U m; n
}
: E. c$ u* i8 Z4 ^; `0 E5 U' B0 e# G! ?; A& A! ~
DWORD i;
0 J& n& D8 ^& q5 K0 Z4 S3 _ SP_DEVINFO_DATA DeviceInfoData;
7 m4 z# e, S+ n ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));; i& h4 p) F2 t. n! g
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);0 c! C) C; _ R
( T6 L: ~' V4 w0 t6 K. V3 H9 q
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)- v0 W" `& Y/ D S: e9 R" z+ u8 L
{5 h. d6 W- P, K9 I9 \2 i
if (1 == nStatus)
5 Y3 H) s; l/ O* M& G% X {; Z9 ]0 ]# T- P/ I+ g% C M# K
StateChange(DICS_ENABLE, i, hDevInfo);
T1 \. Q0 v1 R }$ y* s1 a# g7 Z9 c0 j
else if (0 == nStatus)8 v: \2 J- F7 R1 _/ T' s
{+ w2 z$ J* O" g C' h5 q6 t1 l
StateChange(DICS_DISABLE, i, hDevInfo);& {; s3 P9 e" g3 A% }1 V, m
}
& Z- e" k! ~# }* E- G7 E2 ~: } m }' }7 F K- g. U& o
! u% Q' R+ Q+ Q8 Z8 I8 t0 X0 c
// 释放 device information set0 H( v6 }$ H: [9 x- T
return SetupDiDestroyDeviceInfoList(hDevInfo); f( l5 m; m" g9 `: w+ m6 F
}. p- _& v5 d; ^1 s1 }
catch (TCHAR * pszError)
3 C4 H( o" N$ w{
) ?$ i5 C! t3 e* a7 C9 F ::MessageBox(NULL,- P4 Z/ t- `- P- ]# g7 z
pszError,' R0 f# ?3 A0 F2 D
_T("提示"),9 t# m6 B* F n* `
MB_OK);8 d; Q: a; z* h
if (NULL != lpszMsg)
, Q/ T! q. x4 Q/ n {
: n" D& X, h2 j7 x LocalFree((HLOCAL)lpszMsg);
- i9 P; Q7 D( Y; {8 M- m } ! y8 @0 [/ s0 X. W* B
return FALSE;
! L& X1 v- G0 u% K6 W* k( S}
# O/ |3 D) ~* F5 [3 J" _. V% D, Lreturn FALSE;
M: V* G5 G6 p% v# b$ }+ N2 I( }}
6 {& I& Y4 _. j+ G4 m
* {* W2 W$ w* N [+ v+ M" l( ?( Q 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。! K; G5 i/ t/ u' f
据我观察,在注册表的此项下下:
) g! [* M q4 ~" h9 E4 O3 B$ h HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\. D' I7 C& l' L" ?5 _/ w
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
$ w- W/ R" ]9 E+ i {36FC9E60-C465-11CF-8056-444553540000}9 c7 D1 @8 ^2 O) s7 a
这个是CDROM的
: V/ Y' F% k% ~- w! G! ~9 p {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
0 h+ T, f M! j L这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|