|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)' X) B/ y3 u( Z/ [+ \- N
! a, H7 ]( d1 r3 p! T2 Q$ l这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
: G$ e' k( R# D2 L// 必要的头文件和要链接的LIB文件, @& W) h3 O2 r8 F6 l& z& d
#include <setupapi.h>
; u/ u# Q* P/ A; h/ T, C#include <shlwapi.h>* U1 \: f% U& } \" ]; @- f
#pragma comment(lib, "setupapi.lib")4 I3 r8 `1 ~- N. H4 T
#pragma comment(lib, "shlwapi.lib")) B6 ^6 K8 V' s& W3 m0 p- Z
; H9 F. p7 b* E$ c# u" @
// device information set(我把它译为设备信息集)" a3 h4 n" I) m8 |3 P
HDEVINFO hDevInfo = NULL;# X8 W; W# D) m) P$ r' \$ u
- H: v- {# B5 l z, z// 出错信息2 a } T' k' E; m
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)# m6 I5 ~8 E) c3 T" C2 @2 w6 A, ?: y
{
9 z/ o. R7 D$ ~0 A2 A0 e BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 5 E; F! s2 [0 [) S
| FORMAT_MESSAGE_ALLOCATE_BUFFER,2 M. b) `1 t4 g" k, d3 I
NULL,
" m0 Y; t9 a: H3 p0 ?3 T9 G dwError,5 h0 U8 u, ~# |
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),8 B# O/ E& l1 w. F1 Z. v
(LPTSTR)lpszMsg,3 `; J8 ~5 n6 M' g2 s$ {
0,7 ?4 z& P {: ^$ J# f! i
NULL);9 c) K! E8 m5 R1 h
! K4 R" C! T4 ]5 z: ^if (!bOk): ]8 w1 u* _+ i* f
{" j9 |9 l3 H7 n4 _" _2 m: C
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
0 N3 N- ]5 V9 E3 y8 o NULL, r! {( }+ p9 |3 N
DONT_RESOLVE_DLL_REFERENCES);
# f& `# `, Z! ^1 U. C if (NULL != hDll). i- \4 P6 \3 E9 o+ Q
{; L+ y) V7 {; f$ G. a
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | ; B0 K+ J1 M& J _3 Z$ {. k
FORMAT_MESSAGE_FROM_SYSTEM,
+ T. U# o. Z: S6 Z$ r hDll,
* C4 f2 [7 F" m9 z4 i/ f9 i4 R" a dwError,7 k- ^1 [# {3 K; k' ?7 Z
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
3 P& I7 O) B1 ]- N5 x: ~ (LPTSTR)lpszMsg,' s6 ]$ {7 E0 x; z& M; f6 l) x g# d
0,- H/ X' T$ N4 v: C0 ~/ ?; N: c
NULL); w, m+ G, }7 x5 C8 W
FreeLibrary(hDll);
5 S6 i& \* X* H% U3 G }. x. r0 d# C w* d9 \
}
# { b# Y; i! e1 [' k' C( b}$ R- d$ B( K; Z2 t/ d
0 l( L; j9 a/ m, M0 ABOOL ChangeStatus(DWORD NewStatus, a7 J& l% O) t# E/ q
DWORD SelectedItem,
- ^% z$ M1 T4 {% `4 l, ^. s2 U# e HDEVINFO hDevInfo)5 ~& @ X e. L) r# y$ l v( v
{: J/ c' P3 _; [
LPTSTR lpszMsg = NULL;
, } G; O( c, G$ r1 C: U( _HCURSOR hCursor = NULL;
% q& V" j8 g5 wtry
0 Z' i1 p6 `1 C" m& E$ z: X9 P{
5 W0 @: E7 `4 o SP_PROPCHANGE_PARAMS PropChangeParams =
9 B' S( Q8 P8 Z) @7 Q/ k4 ` {sizeof(SP_CLASSINSTALL_HEADER)};1 A% X/ Z5 J. c1 s2 v; e) Q. I
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 9 Y3 R1 `( x0 E1 S
9 @0 {' K1 l; x3 t hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));* ^/ U' n0 l6 v# T7 R
- j1 J0 A4 ~: V8 l8 k! D% O
// Get a handle to the Selected Item.5 L6 r& L& u4 }7 ^. |
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))" m6 A. X6 R. t2 }
{& F( R& t+ c9 w8 L3 J
FormatMSG(GetLastError(), &lpszMsg);9 f+ z0 U2 o! a: Q
throw lpszMsg;+ S' M7 D1 U' x0 C `9 e
}) L# l! Y$ P7 G/ }2 F
1 R/ V8 F6 i, a; j0 \3 p1 W
// Set the PropChangeParams structure.
& D7 K# Y8 @; Q- j: w5 L PropChangeParams.ClassInstallHeader.InstallFunction = " k# F' c" s9 g
DIF_PROPERTYCHANGE;5 o* Q( k2 V' J' J* \: ]
PropChangeParams.Scope = DICS_FLAG_GLOBAL;' h6 h& ~; z1 Y% V) m* ?
PropChangeParams.StateChange = NewStatus;' Y$ s3 R ?4 F; K0 e
3 j' l2 I! r: t; H& } if (!SetupDiSetClassInstallParams(hDevInfo,
+ ^2 g+ j" f7 N) S/ t) p% ?# s &DeviceInfoData,
" P- u" o3 ]9 k; Z: e3 K/ q (SP_CLASSINSTALL_HEADER *)& ropChangeParams,. O1 O5 C0 A. J0 `9 Z% p5 r; X3 b
sizeof(PropChangeParams)))4 D- q% I. u1 ~! A4 L6 ?# ~% N
{
W/ L ~/ p& f- n) I1 J) n( Z6 k FormatMSG(GetLastError(), &lpszMsg);
; H) A3 i0 Z7 O* T" |5 m throw lpszMsg;1 V K" o0 i1 Q4 @2 Q$ M/ r
}) c* x1 I/ c2 z) Q T% u2 H8 P
# H( y! D, ^9 \0 L3 x0 d // Call the ClassInstaller and perform the change.( l& s( N5 P' A
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,1 e; G% _9 n$ e4 g
hDevInfo,
$ d( `. m! J6 w% y+ J; L &DeviceInfoData)), v% Q# }# l; i; b+ `
{+ K# X, v4 |& @
FormatMSG(GetLastError(), &lpszMsg);) F* ]7 c, W. y7 ^8 ]
throw lpszMsg;. ~. \& Z1 p0 m8 p8 d$ G
}
% q0 }6 o* z# ?6 S$ L( l: A+ X& Q" L7 b+ w# P* h: L' i
SetCursor(hCursor);
5 B2 F1 Q: m' A4 X+ T return TRUE;
/ L; |' ?) ?$ r3 V$ Z}
. Y% Z X$ M& b* A+ _catch (TCHAR * pszError)
7 A. o9 Q/ U/ [, j{# u+ G% O( B2 X+ K" I; H
SetCursor(hCursor);
) U0 g% C0 x" o2 K9 J ::MessageBox(NULL,- L8 ~" n9 \) @
pszError,
/ _0 b: Y8 ^ R0 n$ _ _T("提示"),2 ~" i& o" [6 Y, b& I1 K
MB_OK);
/ I8 y' D$ H% T+ O& f( z8 \ if (NULL != lpszMsg)
) P7 u; `) @% r B3 ~& C {" e9 T, r( T) G4 u' r6 H8 {, q
LocalFree((HLOCAL)lpszMsg);. ?8 `6 z8 {+ f6 T$ t S
}
' v* r- Q- c: `) m; n) l, ^ return FALSE;- M$ f' e3 ?# Y) r: x1 `. ^
} 7 M$ j6 B! a c# R3 Z: h* }3 }
}
9 R& G% I, P3 A0 }, S
" ~+ ~' h. i: f$ O o) }( b// 这些设备的启用和禁用主要有此函数实现5 s9 h9 Q! ?% F, V6 P/ o( q
// 参数说明,nStatus 可取3个值,-1 :啥也不做. p5 i1 ?2 w Y/ b% N
// 0 禁用设备,1启用设备。+ Y( g8 T9 @& f6 P) E
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用/ M" Y2 Z! s1 b2 t L
// 也是可取3个值,0 代表软驱,1 代表光驱( w5 c" n5 D0 S5 f, s) W9 {
// 2 代表USB
% z* y, r# \# R; l/ D// 譬如要对光驱实现禁用,可以这样调用此函数1 g( \3 g _- l% Z+ l
// ControlDisk(0, 1);" F4 E2 G2 G4 [; U' ?4 n' v
BOOL ControlDisk(int nStatus, int nIndex)
# W+ J, W$ Q; s9 V9 ]- L: S{$ f% ~1 w+ h. b, @% J
if (-1 == nStatus)$ V& P/ h/ t' B
{3 x: R" q' a. Y2 T$ i# A6 g" b3 b
return FALSE;- I% f4 H$ C& U- g8 t0 P% e
}
# }4 F1 E/ r7 m' _6 V3 G' A U n& W+ t, |
LPTSTR lpszMsg = NULL;
: _) L) [( e1 ^! [1 p' U( r5 }try! G# K! Z4 F* q" D: A7 S4 g; E
{
T5 `$ V# l, Z+ {- p5 V TCHAR * GUIDString = NULL; ]* V+ p8 G a
GUID guid;
- U% X$ r8 H7 c, b* Q+ E ZeroMemory(&guid, sizeof(GUID));$ `$ s: E0 U6 Z( p" p: Z
switch(nIndex). O8 V6 S6 B# ^. n1 A
{
3 D' N2 w0 z# f! `5 x) l case 0: // 0 代表软驱) E6 }, e" F f9 u' Z6 ]" l
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
. p: `+ a& @! F7 ]4 ~9 L UuidFromString((unsigned char *)GUIDString, &guid);
' O1 _# r' F, z5 h7 E4 p break; - o. X% x+ A9 Q/ C1 @9 a: z5 J
case 1: // 1 代表光驱 3 \/ [! w* e* O, s5 a! ^; L. p# I! C
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");/ m3 ]+ t' O. K; G
UuidFromString((unsigned char *)GUIDString, &guid);& }- \1 s0 A: {* [/ j! `1 Y/ o
break;3 K7 H0 m$ G3 }- s ]" {7 P8 p
case 2: // 2 代表USB
* A X5 O4 j1 [* h' x% }9 z8 D GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
, B6 t% q0 a$ y$ Y, B: k6 q+ I% m$ ^ UuidFromString((unsigned char *)GUIDString, &guid);
; l! {2 P% U6 z* F4 P break;
, D4 G1 k. B2 |) e7 \. a) | }- h- B6 Q; Q& B( l. D2 y2 n; w
) z, D3 [' w& z hDevInfo = SetupDiGetClassDevs(&guid,. q% S4 Y7 e. Z T( X9 ]# K
NULL,. Q* r, C# Z& v$ M# d
NULL,
. @7 k4 E) x( D DIGCF_PRESENT);8 m% _* S$ c4 W1 |$ s3 b
if (INVALID_HANDLE_VALUE == hDevInfo)8 |) z! `. m( T4 ~
{% t* f, k8 x, X- T0 Y0 k
FormatMSG(GetLastError(), &lpszMsg);
2 E3 e" o8 ^& O throw lpszMsg;
7 a$ O4 b: Y3 X6 L( U* u+ O% R- J }, W5 ^! q- P7 |$ y: v0 P* Y
) @2 N) d, d0 Q a& \ DWORD i;1 H$ p0 x0 r2 N3 y: e. {& O9 [
SP_DEVINFO_DATA DeviceInfoData;# z0 ]# e- e5 I" G
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));6 {- O' N4 E: q8 c8 o: m
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);( ~ }5 z: ]: F/ `
* D5 m2 a) T' ~% I for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
* b3 @$ o: R, J0 o% X( Q {
5 w& u$ J& N! ^* M& O7 y if (1 == nStatus). m2 n' X0 f6 w2 C6 \' ?* ^
{6 |2 L9 w. I1 y! o: p0 T
StateChange(DICS_ENABLE, i, hDevInfo);
: a1 N) r3 i. {9 n& x }
) O9 U6 h' }8 h# f else if (0 == nStatus)
$ h( J( @2 T9 N% w, i, F {
: Z! W _7 y N& Z StateChange(DICS_DISABLE, i, hDevInfo);
5 ]0 B9 e O0 S: D6 B3 H' g } + ?4 h6 d7 ~/ y
}2 ~/ ?& `2 k' k
4 Y/ c( c: Z7 r/ g+ W5 _. p0 F // 释放 device information set
1 G2 G; i, H$ U$ J$ N& x return SetupDiDestroyDeviceInfoList(hDevInfo);% j' Q2 z) n/ h5 [& d" A
}4 H( A9 v9 F/ G( i3 j( z3 P
catch (TCHAR * pszError). U6 p: [2 g5 D
{
% G/ B: |. }! i) m7 s3 |0 L ::MessageBox(NULL,
. m* P1 E: @, V pszError,
$ t3 x: w, n, K* w& k( @& k) t _T("提示"),
# I3 W& s x: y/ \7 D6 h* l6 X MB_OK);
6 o: T) T$ N% `6 t2 n5 p9 I if (NULL != lpszMsg)
# Q6 s2 f% I7 N7 X3 w' M; t {( ^& k/ Y) }& Y
LocalFree((HLOCAL)lpszMsg);: U }: g& x* @) M
} 6 J+ U: K7 N7 }4 D
return FALSE;
% E3 b5 ^3 y8 q7 L( e. O} q9 h' l; `* T" K
return FALSE;! d$ Q+ L- P Z+ v7 ?
}
& f$ L9 `& X' t( b% x7 ]# C9 L [& D& |( C. i2 E5 t7 D) g
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
' y+ H5 V% \& l5 R" r+ b9 n 据我观察,在注册表的此项下下:1 K N: _) ?0 ]% p
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\# V/ {' |) d2 V8 j. P! ]. K# Z" ?' P
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
" p; |1 z( d; @. j4 B {36FC9E60-C465-11CF-8056-444553540000}2 S7 X2 F5 N6 l, c. O
这个是CDROM的
3 O8 d1 Z$ y" L" W! K1 N% s. l {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。3 l5 s- p* D8 r3 W3 n
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|