|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
% Q6 [; y l" F) u4 z8 M
! [/ k) Y1 y {1 b. c& S" h这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:8 a( i0 d" b0 t# J$ L# X
// 必要的头文件和要链接的LIB文件
; J4 f! K6 b c1 Y8 f6 N# b7 |#include <setupapi.h>
: ?/ t6 B) h3 s9 ^#include <shlwapi.h>
3 x2 w' K c) V m; M# p/ y#pragma comment(lib, "setupapi.lib"): \" A5 m% ]% t$ Q% B
#pragma comment(lib, "shlwapi.lib")$ ?; b% G# T# q! F$ ^6 W
/ p$ H1 t+ Z+ H4 A// device information set(我把它译为设备信息集)- F, l9 T5 p+ }' E) T
HDEVINFO hDevInfo = NULL;
$ |6 R/ q/ t' y: F( y
C! d* k5 W$ S: G1 g) O! `) ^// 出错信息
& }5 k; \8 K$ ^: Svoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
$ I$ \: w o& C2 M4 `' B! ^4 Y4 m- z{ ; R+ I1 \. p3 d4 `$ P( n j
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + d( I- s8 M/ p( v( h
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
8 v% F$ ?: h6 a( S NULL,/ R* w, c v5 X4 y! y" r4 y
dwError,: ~' N: {! g9 A' Y* c
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),' W k8 o' g0 g6 I
(LPTSTR)lpszMsg,' o' \; p }& V, M" p w! K: f
0,( [% Q- Z$ `" D5 S/ k
NULL);
2 n: \; v# y+ p l
# r, s0 r% D0 B, T$ qif (!bOk)* a/ c$ g. f8 k! n! E$ k+ B( y6 B
{
$ N9 P# K4 i& X$ a- o7 Z* L7 i HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
6 T+ D: `4 ~" A1 l1 t( N9 h NULL,9 _# j3 I) C% m. @$ E
DONT_RESOLVE_DLL_REFERENCES);- T5 G2 o6 ]& I
if (NULL != hDll)2 N8 X+ H+ l9 ?, g* i1 p$ q4 A
{3 _: V& U+ x8 j' U5 W
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | ) X. k4 `3 }" |7 h
FORMAT_MESSAGE_FROM_SYSTEM,
# y, h% b0 q8 h3 d% ^ hDll,
. s9 W- K. h& g6 y7 @8 b dwError,
& u! [- H) z. Z$ O MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
, \ v3 x* q5 i# n5 O9 G (LPTSTR)lpszMsg,
+ k0 _$ p" ~$ c# V9 V- t. g: Y7 L( l 0,' F' C. y* w1 L3 m9 n: |, f
NULL);
4 g$ U. \! {$ d3 ^7 V; O: O- `7 i( B FreeLibrary(hDll);
1 [; f1 w8 l! P( p0 u9 [9 R }3 N- @2 R* s5 i) Y8 a2 ?
}2 j6 Y0 p8 n% U& |- y
}
$ o" _: N9 B2 X0 _6 ^) Q: _& |/ M. u7 Y V& F) y( ]
BOOL ChangeStatus(DWORD NewStatus, 6 V, F" T% O& P7 B- L5 m
DWORD SelectedItem, # C( i& s; X0 i9 a( }, E& u* r
HDEVINFO hDevInfo)
3 e) Z4 Z1 H; k! G. G2 N{
$ Y- j) ^8 y. I% y: M+ rLPTSTR lpszMsg = NULL;* V7 H: _- T3 o; v0 w: K. |& d
HCURSOR hCursor = NULL;
* P2 T) t" w9 W5 L2 T0 B, Ptry) J- a/ M% a7 `1 L
{
# c7 ~! M% \, |7 L SP_PROPCHANGE_PARAMS PropChangeParams =
: L: U A: p: a& g5 O {sizeof(SP_CLASSINSTALL_HEADER)};7 u' g; f+ O1 l+ w& o0 m
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; - r9 f5 x5 N( y8 v0 B
5 X/ o9 ?' i4 u( l1 x' [
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
/ k- v: V/ m& \9 `3 ^( r, u: z! X6 m/ O5 M7 Q
// Get a handle to the Selected Item.( J! z5 q/ ~! x
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
( G& e2 ^9 t6 n# a* O {6 K$ L% ]8 l* w! [5 M
FormatMSG(GetLastError(), &lpszMsg);
) s/ O$ z# }- {' d. b throw lpszMsg;
: D! i( r, s) s# {! a* I }7 u2 n4 Q E B' K+ U6 P$ E
! I' o5 [8 `$ O4 T
// Set the PropChangeParams structure." z& P# S: K/ }) m
PropChangeParams.ClassInstallHeader.InstallFunction =
& C6 t% ]& Q) a DIF_PROPERTYCHANGE;
% q2 m0 g, c0 ^( n PropChangeParams.Scope = DICS_FLAG_GLOBAL;
f4 r+ O, d! ?7 ^+ k) W3 H PropChangeParams.StateChange = NewStatus;7 F1 |. d5 H. ^1 f* ^( u
" w% L4 ?6 S! Y; ? if (!SetupDiSetClassInstallParams(hDevInfo,
/ Q6 C: c. @' L6 n &DeviceInfoData,2 g" Z; n3 q. S2 Z2 w
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,2 K6 R8 ]: h, a
sizeof(PropChangeParams)))( i7 ~3 C4 t, j* K9 C7 T. m# [8 Y
{3 {% L- }; y* S* g7 e5 G' V* C
FormatMSG(GetLastError(), &lpszMsg);! x; B, u/ N; O5 w
throw lpszMsg;
6 a4 G- y; c6 m) I. R }9 _9 _2 O% ?5 e3 ]: ]; N
+ k8 E, \) Y! ~2 h // Call the ClassInstaller and perform the change.1 W* o, |, H: a4 M4 r7 v; m$ Y
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
2 c& u7 c" I3 z3 W3 ~& K8 D. W hDevInfo,
6 {3 K! r+ O: @ &DeviceInfoData))( b& q* P0 A+ P6 C
{
; U1 H C# l; J/ ^ FormatMSG(GetLastError(), &lpszMsg);
" q$ R7 D; Z2 W5 O( y throw lpszMsg;* C: q9 A7 ^* G8 e1 g! x5 I7 a
}1 `" H$ O3 F7 G x' _* d
+ L/ _6 k4 f" F, B0 l SetCursor(hCursor);
- Q1 E3 g @, } return TRUE;
X9 o9 W( C) I9 r( Y( @; D- Q}
6 M8 V v" m9 K, W# Mcatch (TCHAR * pszError)! x4 j+ J3 S, }5 x9 V
{5 D. x0 o2 F6 F5 o3 y
SetCursor(hCursor);* K9 G8 s% A. ~7 }' Z. T/ S
::MessageBox(NULL,
+ N! o, l O4 u ? pszError,- G3 a) E; k& @6 o
_T("提示"),
4 ~, C: P- a( m; {, g) \! Q MB_OK);
( e& D( L( z/ o& ~) [ if (NULL != lpszMsg)
# B, Y0 C: ~+ w2 f1 i; w {
- I, Z) C2 P4 x1 v LocalFree((HLOCAL)lpszMsg);( N) o( g. j, J1 n5 s
} # U1 A1 k: Z, Z Q- ]
return FALSE;/ c/ H0 R/ M }1 c J/ }0 N$ Z
} 2 M$ d. Z- N) l- X& F! L
}
0 @1 t8 l9 ~+ |1 |; c2 {# I0 h7 k9 X4 t( _9 P
// 这些设备的启用和禁用主要有此函数实现
* m. f' ~0 w! B: F4 \* C// 参数说明,nStatus 可取3个值,-1 :啥也不做
/ h! p* m9 X' Q ~: g' c/ g// 0 禁用设备,1启用设备。
4 {# j% ?# l+ D( o6 d7 D9 V ]: @5 @// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
; _, Y) G {0 Z// 也是可取3个值,0 代表软驱,1 代表光驱0 [: B$ S. f" n) ~4 {
// 2 代表USB0 B! |1 ]1 H. y# `3 [/ f
// 譬如要对光驱实现禁用,可以这样调用此函数$ z0 G/ h- F- _ A
// ControlDisk(0, 1);7 Y6 O% K# @( Q
BOOL ControlDisk(int nStatus, int nIndex)) R- {( ` W$ b& G
{
% T) Z9 M4 B" Rif (-1 == nStatus)) K: ^2 H; W! M/ L7 d
{5 {/ o9 B( g2 [
return FALSE;: b; u% V/ _; T5 }: o( ^! T5 y0 e
} 6 J) p6 u; [; y- y: u' q
& q- A% _1 J% R* b+ ]$ J, r- ^LPTSTR lpszMsg = NULL;
+ }7 K' C1 D3 @+ g. ltry: j: d5 |; B5 ^. R( o4 T
{
8 Z2 z, ~. I# K$ Q: g. a+ c TCHAR * GUIDString = NULL;5 q. h& l# D& f# F0 H
GUID guid;6 \: ?. q6 C# y6 G: ?* ?; P
ZeroMemory(&guid, sizeof(GUID));; ]' P4 t! p7 k$ s* T8 H2 y# a6 u% {
switch(nIndex)
% _4 n& @: y. u0 S {& D" Q) X8 i) Q2 g5 |
case 0: // 0 代表软驱3 e6 m4 W/ V" ]% W8 k
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
. `- @: X7 u; d+ m1 T0 ^) _! n+ A UuidFromString((unsigned char *)GUIDString, &guid);
# [6 V# B1 {0 t2 [0 X break;
+ y" q9 [) I) X5 U3 k8 R case 1: // 1 代表光驱
4 @; k8 V" y& s7 W: h8 g2 j5 p GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
3 m" w/ r/ }2 J% S; s( \ UuidFromString((unsigned char *)GUIDString, &guid);
' c" J9 Y @" Q7 C* i7 l3 W4 |9 ^ break;/ h6 p _7 H3 G# ^% p& M- t
case 2: // 2 代表USB
9 B5 ` ~% T' }$ T7 ^9 V! h GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");% ^. Z. L, A# S2 K) k2 ?6 Y
UuidFromString((unsigned char *)GUIDString, &guid);
0 ], J' @5 _- E/ a; Q break;+ I6 n' Z; b. R
}
' y0 O9 x2 a3 {/ z5 @8 s+ Y- Z" w2 \. F: U
hDevInfo = SetupDiGetClassDevs(&guid,6 [; x0 M1 b2 R
NULL,
9 \2 y/ @2 E7 c: s$ c NULL,
/ n& D- A" {: t# J7 Y DIGCF_PRESENT);
; S# s/ x: W3 z% J5 [$ y if (INVALID_HANDLE_VALUE == hDevInfo)
& d- |9 @( s2 c5 H0 ^! i {
8 c# i* k" C. y FormatMSG(GetLastError(), &lpszMsg);
2 J9 j4 E @# R2 z; f0 Z throw lpszMsg;
, e% W, m) z7 {# T }$ ]- g/ y2 Q/ [% b
! a! v9 s* C+ m# m4 H DWORD i;
+ {. k0 e0 `1 P# v: p0 }) D SP_DEVINFO_DATA DeviceInfoData;" Q! w+ Z! {: u: }8 S
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));7 h5 q" C `+ R6 J
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);7 b3 z1 M0 }0 ^7 X. C6 ~$ E
1 X* F" }' @& M% A5 A
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)& t( T( z& M: k% n
{$ p n+ G8 @& H0 z1 G, K% W
if (1 == nStatus)
! ?2 D- o4 Y' _ {
( T( P6 _4 b c: o4 l$ F+ A# T3 l9 S( s StateChange(DICS_ENABLE, i, hDevInfo);" I- ?2 {0 T5 O O+ d' b
}
' Q6 a p) L- g9 ~ else if (0 == nStatus)
$ G2 g* P9 V7 O7 _+ G/ r. y {
- g- q5 ~8 p4 ` E |( M8 f StateChange(DICS_DISABLE, i, hDevInfo);+ y9 G8 ~5 E" f7 P' D
} }8 l! |2 }$ }6 g
}
* Z) D+ |8 p' C* t7 S/ g! [9 O0 @& b _& x% H/ j7 b9 M3 C Z
// 释放 device information set
& V/ _8 t5 h# v. i& ~ return SetupDiDestroyDeviceInfoList(hDevInfo);2 \/ {8 n" E/ |9 v8 N7 R6 ~% D
} i# Q. x: D& m$ v7 ^, F
catch (TCHAR * pszError)
4 m, z0 w* z. P: G{; L8 R% J4 x8 q. \ U0 Q: ~
::MessageBox(NULL,
' g& ^) C8 @: J! W pszError,
4 k( f3 a+ B) G3 q: O& T5 E _T("提示"),1 L w$ K( i. R# ]
MB_OK);
6 }/ `) V3 }( b' w if (NULL != lpszMsg)
2 R: Y ~ A" B {
6 H7 W* R, K1 t$ O LocalFree((HLOCAL)lpszMsg);
5 c! l9 V2 V8 y7 u } 8 C2 t( v9 X( V$ u& w) Y+ ^
return FALSE;( s# v4 r5 x8 I" q0 {
}' ]9 n3 {2 h) C6 l- u( |# J
return FALSE;5 X' h" B' D5 T, Z+ l
}
' Y* i% N$ u6 E* F3 \/ i0 E4 Q2 w$ E- ^ }7 c# c: a: u1 B' `2 M
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
$ i1 V9 v7 S/ p2 Y/ ]& R, M 据我观察,在注册表的此项下下:5 O; `' Y+ E- |) K
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
' T" x2 S8 `) m 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
3 M2 i/ J J @: r; y5 z9 k) h {36FC9E60-C465-11CF-8056-444553540000}0 U3 ~& F9 [ Z1 q) H6 s
这个是CDROM的! r Q6 T) N+ `( E5 g$ Y( I* v; Y* ?
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。( i, b$ F, h) r8 _
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|