|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
( Y& y5 C9 I2 ? ]+ x$ o+ [ k* |- R- q- w
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
, z( O+ R H7 H# Q; {! f0 d// 必要的头文件和要链接的LIB文件5 C5 H+ ]6 F8 |$ M2 {: ~
#include <setupapi.h>3 T4 |4 J& q& L8 S u3 d4 G
#include <shlwapi.h>
; e% v+ p# J6 N#pragma comment(lib, "setupapi.lib")
7 } u* h9 y8 K) F1 ]/ v% _& A- O#pragma comment(lib, "shlwapi.lib")
1 d, C1 @8 W' D/ x$ z2 _2 g+ O# d3 l+ a4 T& D( X
// device information set(我把它译为设备信息集)! g$ A8 ^1 S8 y! x |
HDEVINFO hDevInfo = NULL;
; a$ |! `2 I# X7 S5 F% B# E4 R$ b- D1 `. B _7 T3 Z2 W- r
// 出错信息3 d- K- T. x; f' K; k) t6 e
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
) n( G# h! \. n, `# S& F! t{
+ l/ `# K/ @4 z BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
- A# ` j# R8 f0 k | FORMAT_MESSAGE_ALLOCATE_BUFFER,
% k% ?& I+ y L" t% X5 s NULL,
7 c" \- ~: P' p) C- q dwError,
/ N* o' `3 x; A/ Z+ u MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
4 R+ y. }9 L+ M: O" G0 H (LPTSTR)lpszMsg,
& F7 e7 z n2 j8 o! \0 f 0,' v, ^, F1 f3 J3 P& y9 `$ @
NULL);+ o+ t9 G' a9 v
+ f8 o% z" x; h& R: q1 dif (!bOk)" j* k( _% P& D& s0 P
{) y9 y6 b. D- d( k5 n7 |
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
- W* |$ |3 ^' J8 n5 T; C NULL,% s8 B# {4 W5 n$ `0 b$ w q( R
DONT_RESOLVE_DLL_REFERENCES);
N# y/ ]8 b5 { if (NULL != hDll) g3 H) ~; g+ ^* G a4 W
{
3 M! G- z. A4 H+ B1 {- [ FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
' J8 O* j7 x. }' t$ n/ T FORMAT_MESSAGE_FROM_SYSTEM,% w# ~ E) X" G( y- k+ K
hDll,
; I0 M& p+ k5 i# C) ~ dwError,+ w- N+ O+ b9 C0 V6 @
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),% l5 I- u* J- K" H
(LPTSTR)lpszMsg,0 v+ [# }' p- e0 X
0,
e* n7 h" F# O! p# U NULL);3 K3 y/ Y& l3 U* I0 v+ t
FreeLibrary(hDll);4 W0 E/ `8 G" m1 h2 J
}# ?9 F- r' G6 _! I4 {8 r- f
}
+ @1 n- x/ B" h) O. p- t4 X}
% D# E' o! [0 r. w# K& L$ c+ G5 R4 K/ M( j/ K/ e }/ k- \
BOOL ChangeStatus(DWORD NewStatus,
3 ` r) v m1 W8 {" ]4 N D5 ` DWORD SelectedItem,
: v, Z* T$ Z( }- t HDEVINFO hDevInfo)
1 A: ~ E, x( ~. S' j% q1 K{) B8 }3 [9 F6 }3 S$ ^! o
LPTSTR lpszMsg = NULL;' I7 y! c) E& e
HCURSOR hCursor = NULL;9 P' c9 H; w8 l2 \5 o0 U2 u; E1 C
try
" h7 e2 O8 ^; e3 ^. w/ ]( T{
- U5 j5 \' y- f4 W( }8 j" x SP_PROPCHANGE_PARAMS PropChangeParams =
! m9 U7 ~0 `. \$ ~ {sizeof(SP_CLASSINSTALL_HEADER)};
3 k) ~& G6 c3 q( x' Q8 N( @ SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; * ?' ?- N6 n$ E/ ]+ F$ Y: N
& [3 {% }. K$ o hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
' h3 x& u7 ]/ O9 j) F, G4 E7 `& ]; A. m
// Get a handle to the Selected Item.
7 R. [9 H& T! ]9 Q+ k* K if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))* a2 L( E2 N6 A, {# @
{9 B" H- a1 X6 N9 y! @
FormatMSG(GetLastError(), &lpszMsg);
. x: E V s9 x& U: a. w throw lpszMsg;
1 _/ t- t# f6 N* A7 v9 W- |+ t S }
# q2 D* Q! t {; i) N" r, Q% U6 I$ R$ F8 j
// Set the PropChangeParams structure." L- n) g, F+ _+ X/ a4 K6 {; Y
PropChangeParams.ClassInstallHeader.InstallFunction =
# `, d) U! Z; W8 k. T; c DIF_PROPERTYCHANGE;4 ^8 J8 H( c! I3 a5 i! T
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
% T& ]$ [1 N8 C% W9 A4 m5 Q PropChangeParams.StateChange = NewStatus;
( v" Y3 p! l# O% r0 F2 N
$ O- }0 V8 @) n& l( O: ?% J if (!SetupDiSetClassInstallParams(hDevInfo,
! U* p! J0 ^ l& r. i/ Z/ u2 M &DeviceInfoData,- n; F* J; l: b) p1 d+ |* w1 p
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,$ ^( a+ ?3 ^; y8 T) e0 O: Q
sizeof(PropChangeParams)))
* e# x" a" X d7 n; D { h1 H6 c, s3 M: x9 V7 m
FormatMSG(GetLastError(), &lpszMsg);1 m+ |5 \0 V: \/ \: ^" n I$ t
throw lpszMsg;
^2 S1 w, `4 o }
# K, ^$ P3 i; y% n3 w9 P: A5 o% Z$ e/ P4 h9 ~/ M4 R2 k) v3 t
// Call the ClassInstaller and perform the change.; j t( D. x5 X( J) j
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,) z5 X; h6 u. C* j2 t# l* b8 {9 |6 a1 S
hDevInfo,
0 K5 ^! s1 T' d6 w% r &DeviceInfoData))* {3 O- u' \! o/ _9 H+ b
{
. E2 S% L) [( l% [6 X FormatMSG(GetLastError(), &lpszMsg);" l, u0 \* X+ u P7 B0 w
throw lpszMsg;
, t+ k6 `2 b% t }2 `) M9 u) q7 h
* q) U- N# G5 Z+ ]+ U SetCursor(hCursor); H/ f6 |' g2 h( `4 ~2 q; f
return TRUE;& C2 t6 n- K: P% \& {1 |$ U) u
}. U9 f* ~4 x6 a d; n: H4 h
catch (TCHAR * pszError)
- m8 J, w$ _- q8 z& T{
& z7 D5 e" _. n& f& T SetCursor(hCursor);
4 s+ w% C$ x1 | ]) d8 T3 t ::MessageBox(NULL,
) b9 s) D% m0 e8 m8 J) t3 a pszError,
/ n1 ]# ~& n T4 P* E _T("提示"),
2 w, T& T. T+ {1 { ?* v% H MB_OK);3 }8 t% G: c# N" c S
if (NULL != lpszMsg)
6 c: T* k" z3 n. U* U- S {
, x1 ]1 o+ ^6 Z R5 G LocalFree((HLOCAL)lpszMsg);
# b0 l" y4 k7 n2 O } 5 i$ Q, J, n% }$ f% D6 S5 `
return FALSE;6 Y. J6 l E% S' I$ N
} 2 y% q) f: R2 O% E
}
6 p4 e/ j% q' J4 U
, U! G1 s9 B$ M7 ~* s+ F// 这些设备的启用和禁用主要有此函数实现
8 d0 R9 c7 |7 J// 参数说明,nStatus 可取3个值,-1 :啥也不做
" ~3 @. Z- S( B8 @2 _) g// 0 禁用设备,1启用设备。
( L; J2 n0 M* N/ U2 I9 W+ l% ?8 Y// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
3 y6 G2 R: X4 C7 a% N6 A// 也是可取3个值,0 代表软驱,1 代表光驱
6 a& M$ Y: u. U3 a, k// 2 代表USB9 T2 O: S+ ~) n1 A! D) O* M' a
// 譬如要对光驱实现禁用,可以这样调用此函数
6 ^& L; r/ ^& v) G1 R. p# z// ControlDisk(0, 1);
|, A+ h7 \( d' K! ^6 e, ABOOL ControlDisk(int nStatus, int nIndex)4 c* G* u, N1 k! q6 }
{
F' T; Q7 k+ N! g& j7 zif (-1 == nStatus)
1 a7 i) U, p* Q$ C{1 l, m6 Z# @, u) S, f+ X
return FALSE;% |" p: v6 S3 d; w, G) e5 h
}
: U% Y, E( u1 u7 ?+ e( N4 {8 R. P$ @4 W) @8 P3 R0 F" M+ b% V
LPTSTR lpszMsg = NULL;& S1 ^) A ?* P9 o. I
try. q- V8 f- o( Z
{
) L; j* @6 \* G& ~ p TCHAR * GUIDString = NULL;
! j; n: ^; e2 C) { GUID guid;
4 J+ |& ?2 W' b9 j5 j9 u! Q! _ ZeroMemory(&guid, sizeof(GUID));# `0 E" N$ q: X4 ]$ Y
switch(nIndex)
( a, [$ g5 c- x {2 i- M8 c- [: V% V3 N L# E" F
case 0: // 0 代表软驱
, i& }; _ ~9 @! n GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
9 L& Y# u7 }. {& Y/ h& r UuidFromString((unsigned char *)GUIDString, &guid);- E! L4 y5 V G
break;
5 N( a8 E6 Z4 s6 X3 Q1 \0 a( X6 f4 F case 1: // 1 代表光驱
9 u( Q+ x) S5 Q8 E/ k @ GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");% x" M# C) w, O$ f/ i" Z" _
UuidFromString((unsigned char *)GUIDString, &guid);
2 _7 }& _8 b+ G break;2 c3 F: ^! C! `0 [+ E" S
case 2: // 2 代表USB& I) ^* F8 x4 `% f2 |
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");" J6 L7 h% N! D. t, s8 n3 c0 C
UuidFromString((unsigned char *)GUIDString, &guid);
6 D- N7 a3 h* s# X3 h- D break;' \- a; H6 q; D) V; \+ [8 w
}$ o% O3 w, s9 g
% c6 t8 N9 q* N$ Q" Q hDevInfo = SetupDiGetClassDevs(&guid,
1 V" J* a* T! W# C) j! ~' S NULL,
: O0 ]& R$ g4 x$ j/ L. Y, u# | NULL,8 L/ Z8 B$ J" b
DIGCF_PRESENT);# [( Z+ F5 y+ e! W/ W
if (INVALID_HANDLE_VALUE == hDevInfo)
' E" e7 k8 L% c5 K! t8 O& D, C {$ ~% X+ O- K; b# S) z/ g0 e
FormatMSG(GetLastError(), &lpszMsg);
]" ?0 a. G+ y8 V throw lpszMsg;- O, b! s& J+ \; X4 o
}2 Y3 \0 M$ y1 }; f: q0 I# N7 l
" H1 Y# O" B. Q$ i; d) k DWORD i;
/ S0 D& \' w6 D! s t( B SP_DEVINFO_DATA DeviceInfoData;8 v: N8 }% M; n" r8 d" d( F$ a: p
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
( ^* `8 X0 c4 d* k$ h/ \/ X DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); S& h3 k& A# W7 t! q/ ^: r
, L" Q& I7 U2 p/ B9 Y; C6 @
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
$ w, j- P; j! u0 V, `& ] {
- N1 ` V9 _, I* x if (1 == nStatus)% g w$ a; ] J1 E" o0 x+ Z
{
8 E% C" m- Y# z# c; J StateChange(DICS_ENABLE, i, hDevInfo);
f7 F9 m' R& a2 ~3 Z }
% C N& g' o% P2 l# z: q7 \9 v ~ else if (0 == nStatus)
c; ?) u+ t. h( }$ ? {
! r j1 G8 }7 g! L StateChange(DICS_DISABLE, i, hDevInfo);
. L+ |$ H$ m. Q3 K/ w) ?$ W7 o( n }
' l A' e7 ]# [- U5 n0 [, B }
3 _' U% x0 k6 l# d; c q2 E m Y, B1 S" r" ]
// 释放 device information set
/ U& G L% b) C return SetupDiDestroyDeviceInfoList(hDevInfo);
' W, \! V2 ]) @0 n$ w& F}# [* @7 T' S, T- H6 i: I
catch (TCHAR * pszError)
: q+ v' h( f" p% A& r; G( f{
; y! L; L( a! z+ [6 m# x7 ~ ::MessageBox(NULL,# g: V' j e6 [2 n. P( E
pszError,1 I; I' q4 E7 \7 t
_T("提示"),
+ l7 O% I/ N! O6 }/ \/ k, x MB_OK);
; ~% E5 {5 t- n0 W if (NULL != lpszMsg)
W0 N9 ]& a* z; S0 l) F! e {
5 R, y+ p% T) i9 \ LocalFree((HLOCAL)lpszMsg);' ^; ^2 h' O- T* }' W, N; Q$ s
} ) U% _# p5 o9 c/ D$ u7 W4 i P8 \
return FALSE;. r; A v, i7 {1 p$ G' F. k# t1 E
}
; J4 B& H% r# s' }1 kreturn FALSE;
L3 G4 r8 g1 v$ L}8 J W: w9 I5 C
' E2 S/ f) g5 e" J) c6 _3 K# n 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
* g R- z w1 Y. ]( S! y 据我观察,在注册表的此项下下:
B8 ~" N; i+ M$ y0 u HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
) s9 @. G6 i0 O0 u, [: D 有很多GUID,每个GUID代表一个设备,譬如这个是USB的, h. s5 v# v1 ^! `" X
{36FC9E60-C465-11CF-8056-444553540000}$ `5 ?! w1 T% h
这个是CDROM的# B) v5 X0 l. M8 U
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。. r$ a; `* y& z/ D& U, U
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|