|
(dlutyuanhongl发表于2005-3-15 23:14:04)+ g" ^/ G3 g j1 ]6 Y+ @' D
% C, \6 k, t# G$ s) j* u+ {* E这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
; x2 H% h- D3 N: S// 必要的头文件和要链接的LIB文件4 ]4 d$ M2 O+ A: r9 E0 V6 [9 I1 R. \
#include <setupapi.h>
5 U i% \/ Y& z#include <shlwapi.h>: `- o8 a- \# K! r* z0 ]: Z
#pragma comment(lib, "setupapi.lib")# N4 b! Y% G9 l2 w* `6 X
#pragma comment(lib, "shlwapi.lib")0 d: u/ j2 R2 ~! |- E5 C4 l
1 N7 L8 W6 O1 M& W) R" o
// device information set(我把它译为设备信息集)3 g+ {6 a3 S) \2 J# O
HDEVINFO hDevInfo = NULL;7 ^! G" s m+ P6 w# Y& G! M" V
( {& v( p$ @7 \
// 出错信息; t+ d0 X. |% z: F& y$ Z
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
1 b6 ]: J/ `/ u0 k7 c7 ]{
- w: ^# D1 B# c4 S! F+ P BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
( v! ~& i! h$ t: y | FORMAT_MESSAGE_ALLOCATE_BUFFER,
* z- x/ N3 k' S2 {0 \ l: m' E NULL,
0 p6 k$ t% r2 Q8 A9 e. Q/ Z$ @! P# i dwError,
+ o; t! s: F3 C! J MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),/ K5 f ]1 x7 m! |6 I# q" ]" e
(LPTSTR)lpszMsg,
* q2 f k! A7 F 0,) [+ J1 h1 I" n! B' u0 Y: W
NULL);, N' m# A$ V& m1 {( V
! ~( n5 ?" i- u" }: z, A
if (!bOk)
! z, p8 E( Y" F! f; d y" {{
1 e& H" G3 V* g, ?! ~ HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
- F# J' l+ i! g NULL,
- @: n# f; {! u DONT_RESOLVE_DLL_REFERENCES);( _, g5 k! g5 Y R
if (NULL != hDll). I3 K) M* _% v
{
' l& m# X/ q5 M0 f FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | 8 f1 [$ p$ H; @
FORMAT_MESSAGE_FROM_SYSTEM,: T3 @ H6 {, p6 e
hDll,1 J6 X1 v; k& M4 }5 P/ O
dwError,
: o/ D3 @8 Z) i' c: \ l/ |8 H MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),+ P+ } Q- ^" g T; H; |
(LPTSTR)lpszMsg,
9 _2 F ?9 o5 b0 i+ b 0,
! T2 Q% e# Z6 }8 `/ Q NULL);& b: k* t& ]8 S
FreeLibrary(hDll);
) v3 Y! q4 c8 N% O2 o0 K' f }
: `0 n# l! l/ J | U+ }- p}
& ^# [; i$ ^% D}
) c* C% | V) u! g+ u$ [" l8 B# I/ l
BOOL ChangeStatus(DWORD NewStatus,
' H3 r D+ F7 h5 }' i0 l X DWORD SelectedItem, 2 V3 P4 B- j7 T- M
HDEVINFO hDevInfo)
7 p5 u- H0 L8 w! U! f{
, Y) A2 p k+ |3 \0 MLPTSTR lpszMsg = NULL;4 h" Q) e" j8 s
HCURSOR hCursor = NULL;3 Q! V* ^% s7 V+ p
try* Q: O- x" ^' O! w4 z
{ o( }/ A8 \+ R1 |
SP_PROPCHANGE_PARAMS PropChangeParams =
8 h! E$ w2 G; L* i4 }8 w! g5 ~( B h {sizeof(SP_CLASSINSTALL_HEADER)};
$ a) R" {6 R: t3 d SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
- W! W" _/ s8 j# s
3 k0 L" K5 n0 X s/ |4 j. Z+ C" X hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
, b. m, k' R5 x; I w) |% i/ D2 ?9 C; l3 h9 d5 r4 E
// Get a handle to the Selected Item.9 @8 t* P( W. I" q$ C8 s
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))2 r9 [. |2 c) I- `& q. V, E% f- B
{
9 F: ?. z# k* c( V5 i FormatMSG(GetLastError(), &lpszMsg);
2 j" Y" T* e! }( V+ i! c. E) o3 ]& l- T throw lpszMsg;
2 ~7 t( W! m6 A9 X5 m }
; D4 b1 T! s/ o- V6 I0 T/ ]% L/ j Y* d9 B) N: s5 s+ |
// Set the PropChangeParams structure.
4 w6 E- z) j/ ^) _. | PropChangeParams.ClassInstallHeader.InstallFunction =
3 F) b+ M& L3 T- w5 ^4 {' T; } DIF_PROPERTYCHANGE;
! t$ M t6 Q/ }, n$ E PropChangeParams.Scope = DICS_FLAG_GLOBAL;
" |9 ?$ e# M, ?, h/ V5 E. r$ H. u PropChangeParams.StateChange = NewStatus;
4 \6 @3 k; V9 Y4 p' A" w2 [
! d2 ~0 q- d. r% {1 e& g' k if (!SetupDiSetClassInstallParams(hDevInfo,0 ~& R+ v9 i B3 E, L1 `, g% \
&DeviceInfoData,
: B! _3 p. [" L1 K$ d2 G d( { (SP_CLASSINSTALL_HEADER *)& ropChangeParams,
+ [4 B: [% Q. F1 O sizeof(PropChangeParams)))
: X" n: C$ q4 p8 l9 |$ u! ^- m {5 [$ |' G' f& d0 n
FormatMSG(GetLastError(), &lpszMsg);7 i* N" J' X2 g$ F3 H. C# z+ e
throw lpszMsg;
4 @. _/ Y P0 ?4 E. {) X }
% f5 S( g6 n. r
1 `5 G6 \, }: k // Call the ClassInstaller and perform the change.8 N. e- m. @3 l/ ^" Q, t5 ?9 Y* |
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,! j' S8 ^6 ~( F) E+ _$ H
hDevInfo,+ j$ `* J: x H( \3 W, d0 c
&DeviceInfoData))3 N. q' V E6 U6 |7 E- I, `, ~ F
{& s+ J& H5 }! H
FormatMSG(GetLastError(), &lpszMsg);+ P9 \0 a$ H. a$ M B1 c
throw lpszMsg;
7 i, s" B$ @$ \" ]5 y) X# ^ }6 {; k! M4 Z$ R; m: @
1 h t" O- V4 M SetCursor(hCursor);
0 C4 Z; ?, f3 ^# l8 k4 r+ ~/ Q return TRUE;
/ `, S" E' Z' {; u i}' `0 e3 h/ @: P9 h3 f
catch (TCHAR * pszError)3 G+ y8 @6 \; {% G: p& R5 o
{, r: ^' }( s" l5 c( A# ~
SetCursor(hCursor);# h7 p9 I0 r+ k. N
::MessageBox(NULL,( c$ S* B1 j1 |2 X: j
pszError,
; s9 ^3 f* f6 p! F! }0 g _T("提示"),; d$ q- R/ T% `; P# K
MB_OK);+ n1 R) X' X y8 M
if (NULL != lpszMsg)
3 W, P1 r" x P" L5 q* T b& [" e {
0 d+ H: G( O4 W+ y8 e( P4 O4 G LocalFree((HLOCAL)lpszMsg);2 f( ]" O) e9 C0 J
} 0 n8 {5 `8 N0 x% R7 P+ k9 b D
return FALSE;; @! }9 b. ?: i0 V9 b
}
! P0 @2 ^+ l% k. i+ Y}
: O4 _# h3 a' g' o# l' K% O( x! }8 j* i+ x6 U
// 这些设备的启用和禁用主要有此函数实现$ c+ c8 K$ _: u
// 参数说明,nStatus 可取3个值,-1 :啥也不做1 G( ]' K+ c0 w$ f3 H
// 0 禁用设备,1启用设备。
6 _8 |/ P+ l6 @$ Y* P. Z8 I// nIndex用于控制是对光驱,软驱还是对USB启用或禁用" b" u. i2 _ d, e4 t7 z8 P+ Q
// 也是可取3个值,0 代表软驱,1 代表光驱" z) s7 S& i2 @
// 2 代表USB
$ ?# g6 @/ W4 f1 _& _- K// 譬如要对光驱实现禁用,可以这样调用此函数
3 E' |0 _) {. e" j$ P. H1 u. e3 o// ControlDisk(0, 1);
4 V, Q& o, B) k0 vBOOL ControlDisk(int nStatus, int nIndex)1 ?8 ?7 O6 n: K% Y
{
/ O: L9 i8 P3 x7 Pif (-1 == nStatus)
6 f0 S2 {" ?- C6 d: S{
C, R% n+ U' b1 \1 W' h return FALSE;
+ p. Q- `( I' ?6 a5 E. i$ _- A}
+ @/ v' h8 {; A: {; V, U. B7 T& _" ~0 E, c" I
LPTSTR lpszMsg = NULL;
! {4 r% G# n9 T8 N! Y4 l5 wtry+ @' J A3 i0 k# m7 g4 g1 g; P$ _: o
{8 k* {4 u. d% w( p6 ?% T3 m
TCHAR * GUIDString = NULL;, b2 ^, C& r+ }$ Q) t8 O
GUID guid;! D( I# i$ g% [0 d
ZeroMemory(&guid, sizeof(GUID));* T/ x+ l4 @5 `. @4 ~2 w; V
switch(nIndex)
1 f8 r1 b" Z& A0 I. ~7 X6 l* i; s {- o u/ z- Z9 `* L+ `8 R' M
case 0: // 0 代表软驱
* E% H5 ^4 g9 S) R6 f" | GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
) Y' `' y+ d, T: Q8 u4 G& } UuidFromString((unsigned char *)GUIDString, &guid);( e" r! j: X* ^4 P% ~! w3 O: ]
break; % B) Z+ T+ ?3 ?: b* d
case 1: // 1 代表光驱 & I$ z% ^ F4 T
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");+ h7 e& N9 @& P- q" c1 |
UuidFromString((unsigned char *)GUIDString, &guid);: N% T0 V% q6 v+ V8 K- m! ?
break;
+ n: c% f. \2 F case 2: // 2 代表USB: k% a: ~7 j$ t. F% C$ _
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
; A1 q, M7 `3 E4 e2 ` UuidFromString((unsigned char *)GUIDString, &guid);/ h/ ^$ `9 T {7 D' V
break;/ g: _& B C3 ^0 i, ^
}! Q8 }+ I1 M/ z6 ~" I
* h: u5 v! @& @( K$ b5 y5 j$ n
hDevInfo = SetupDiGetClassDevs(&guid,
J# }& s# z! f) \, }" K7 U NULL,* s" R: T7 F( O" X
NULL,
4 `8 N# x9 a, @& n# }" G( @$ ^! o DIGCF_PRESENT);- Y4 S* v! ~5 m6 j/ y
if (INVALID_HANDLE_VALUE == hDevInfo)
, @$ m$ [% p- J- x8 }9 W {' u! }$ Z2 E0 h% V& p
FormatMSG(GetLastError(), &lpszMsg);
q4 X# n P- x4 ~ throw lpszMsg;
3 d3 A# P* j! k I7 d }
z: m" ^4 n, Y3 S8 C5 y
8 I3 l. _* j& ?3 ^( _- @( [ DWORD i;
2 t. F2 |5 w& g$ n- K4 r SP_DEVINFO_DATA DeviceInfoData;6 B, F8 w2 p# P/ L% ^, v, F4 P/ W
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));' _. H! |" [* U0 u1 ~8 N
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
$ U5 ~) r- d3 Q/ L; e5 w
* e& A: J0 `5 h) r) F5 L1 v' U for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
0 f M1 H& x$ h/ W* w* h+ o% {+ { {3 {9 U* J" Y" L7 B9 S% T
if (1 == nStatus)
. q6 L" |% {0 c1 U+ m' a {9 j9 ]- p" q- K( Q7 o1 e) D
StateChange(DICS_ENABLE, i, hDevInfo);
) N+ C i, ?' z* `( m2 \ }: z( X- {- @" |; b
else if (0 == nStatus)
' h! U% i& F7 Z; c- O {8 t4 S7 U. c# R7 G9 l2 X& D, x
StateChange(DICS_DISABLE, i, hDevInfo);* H# ]. n" x! Z( V' E0 o
}
7 ]- E7 [7 D; N/ w7 k }, r3 X0 }# ~, H i5 I$ H
* p9 T! w: H6 k/ R
// 释放 device information set! Y' ?+ _* N6 l F1 I& L
return SetupDiDestroyDeviceInfoList(hDevInfo);
( S( \7 R5 s V1 ^9 _}/ _3 V- s5 {; p
catch (TCHAR * pszError)3 L9 j# V/ u- A6 E. n: o7 ~: e
{
% X/ m) V ~) K5 P& w- m ::MessageBox(NULL,
2 e" n4 ]( f9 K# l ]5 e, x1 H) G8 @ pszError,
% ^& e7 ^/ w/ j _T("提示"),$ `6 p2 g; r% h
MB_OK);
% E9 w& ]2 p" y [/ J3 X if (NULL != lpszMsg)( ?7 a t; @$ j1 ^6 u$ p( n- j1 G
{
- C1 ~# R( |4 @' N2 ?* s! [9 E. P LocalFree((HLOCAL)lpszMsg);
; f7 f5 o4 z1 Q, z( ?- j3 V l; ]* B } ! |! ^0 C. o2 p4 t! x1 F) s
return FALSE;
2 E% E9 p9 ^$ K, r* W# t$ a}1 v: a- a, z, ]8 ~' R1 Z
return FALSE;- T# S/ M+ j0 J a l
}2 T9 e8 `% d& r1 \2 a; D0 L5 Y0 h
4 x: f' T ~3 p- V. c 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
2 V/ {# O; @) l3 |0 | J 据我观察,在注册表的此项下下:* y/ {0 R- s+ h' z- k
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
; Q0 p7 s* S' { 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
& E1 c; S `- J+ ]- @, b- F% ^ {36FC9E60-C465-11CF-8056-444553540000}4 _, C7 [0 ?! ]( l
这个是CDROM的9 n6 @: h0 S" f1 K0 w5 M
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。- ~6 Q6 [: b! E& r" h5 t( h. u0 h
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|