|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
5 y( P9 I% ~( c* V1 y! T2 Y4 d- U; F% e, S
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:$ f, q( y; u ?4 v2 T
// 必要的头文件和要链接的LIB文件
: y$ C) l. E% `- A& |#include <setupapi.h>
! a) r- \/ e: {7 E0 _#include <shlwapi.h>
( @" s- |* H3 }/ K#pragma comment(lib, "setupapi.lib")/ ^" D: U2 u! S2 D5 n" u Z" M9 r
#pragma comment(lib, "shlwapi.lib")
. D8 F. g: W& s) O! Y
$ l+ f% f( t. K0 J1 U// device information set(我把它译为设备信息集)8 M/ v* h8 w# G& t1 ^
HDEVINFO hDevInfo = NULL;) H5 P' z6 a* }
& Y% y J: R2 t/ {6 c7 z// 出错信息
! c# t6 j( O: P3 `void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
5 C; s. v2 c/ E- M+ V{
6 u/ I- H2 r: X" S }2 L BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 3 b# ~0 y( C |% I- Q
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
! V6 g F( P U+ A1 x, A NULL,
+ ] ]% A/ o4 i# O& k# {0 x dwError,2 X* U; e5 }+ x+ r2 ?: @" p
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
0 y3 n) Q1 b: ]% b (LPTSTR)lpszMsg,, U }1 N7 e3 O3 A) z
0,
+ U! E! Z3 P' ?8 Q NULL);+ v" k1 D) r9 V, H" o5 F8 N/ U
/ ]' q' h8 L* B. \
if (!bOk)
! }, d- q. G4 Q* w2 l" |1 E3 b% f{+ i6 ^8 F5 {- Y$ L1 N! z
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
9 g* ]* R- h5 t/ Z% { NULL,' T# A3 S+ g4 _ i9 a
DONT_RESOLVE_DLL_REFERENCES);
1 Z) h; j& h0 g8 L& f0 f if (NULL != hDll)
" Y; v+ N0 ~% U {
$ T5 W: |: g8 t; V/ ` FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | 3 `( @, B: C9 v4 T
FORMAT_MESSAGE_FROM_SYSTEM,' h' X x3 B' J% p. z6 n0 d1 b! Q: y: ~) s
hDll,
9 R% V3 C$ y/ G/ O ]& w' M$ ^ dwError,
; f. u6 O p. ?0 ~ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
2 s% T5 |' d, r (LPTSTR)lpszMsg,
5 ?" j% I# k! K9 \$ D 0,
/ k$ v0 G6 U% I2 b/ s" A/ {- o& ]/ ~8 ^ NULL);
. e. k1 ~& F% ]/ D* C) ~+ _ FreeLibrary(hDll); j1 b6 Q ]* d$ o7 W
}
6 z5 }) U a* f3 M$ \( N3 {4 L4 V}
! W# ~/ h4 l5 p) v6 [1 c}
9 i; q8 s4 @0 G
9 d# ~0 k T" G% XBOOL ChangeStatus(DWORD NewStatus, 5 c9 ~4 ^- J" |$ X; g2 N2 | e
DWORD SelectedItem,
: h* w) k1 {' W& B HDEVINFO hDevInfo)+ ^# o _6 ~- {5 Y% I; u; `
{
2 v8 J; m' [8 T: [" r# dLPTSTR lpszMsg = NULL;
, v' E' p* k1 T$ N4 V" j7 l' LHCURSOR hCursor = NULL;
3 s' P; V7 a: btry
1 a2 [9 C! R4 \7 x4 w6 V+ n+ n{! s( K3 S" T% H5 V E% S3 d7 |6 r
SP_PROPCHANGE_PARAMS PropChangeParams =
9 Y% q7 c/ ]! ^# N2 V; e {sizeof(SP_CLASSINSTALL_HEADER)};3 }4 u- M( S2 w6 I
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 8 d& U1 P8 A. ~; H& ^: A
+ Y1 n2 e9 q) i& U4 J hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));- g% E* A* W/ [9 Y, t( |. R" q
0 M. i3 w$ L* m
// Get a handle to the Selected Item.3 z* F0 ?/ Q, D4 \- R
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))! ~( `) v5 G/ l3 v' B
{
1 H( d$ H1 |8 ]8 A T FormatMSG(GetLastError(), &lpszMsg);
, q' W. ]5 U4 p+ s7 g& Q throw lpszMsg;9 a/ S+ m7 Y. k+ H" `9 p
}. g- k3 n. E! }
]3 w4 V( c& J1 s% Z4 K4 O# r
// Set the PropChangeParams structure.
6 L. H0 u) x# o! t3 {7 k PropChangeParams.ClassInstallHeader.InstallFunction =
' E2 t5 V8 v- @ DIF_PROPERTYCHANGE;
7 D9 A3 M' @/ m( o PropChangeParams.Scope = DICS_FLAG_GLOBAL;
% H% n7 b0 F4 u* ^7 l9 X6 e& { PropChangeParams.StateChange = NewStatus;$ J9 y7 m1 t% \: x- s5 T
4 ~* D5 P* d6 b+ V if (!SetupDiSetClassInstallParams(hDevInfo,: |2 {. H+ m3 A
&DeviceInfoData,
& x: w1 A/ Q% M) J4 \! \2 \3 z% _ (SP_CLASSINSTALL_HEADER *)& ropChangeParams,
1 y8 w+ L3 ?" V) K; N sizeof(PropChangeParams)))( K" D4 a0 z* y) [1 | s. O
{- ^- _% v' M9 e+ C
FormatMSG(GetLastError(), &lpszMsg);4 t4 X1 @# g1 M; Y- \7 V2 U
throw lpszMsg;
& y0 |* r3 @! { }9 B2 X9 R5 f/ g4 ~( |) j- c
1 G# p1 q; Y( G( U; ]' P' A% D- ^ // Call the ClassInstaller and perform the change., I* v1 o; E5 Z8 P0 }, s
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,. o# \: V/ O; a2 J# Z, d/ ?+ [6 o
hDevInfo,
6 u# T/ x- h! ]. U3 p: W5 j2 j &DeviceInfoData))/ o# e" k0 U: r' N& n, A( s
{
; h4 q; ~7 A- P" n7 T+ F FormatMSG(GetLastError(), &lpszMsg);3 q2 @! a9 A; \/ @* b7 D" `
throw lpszMsg;
& O# E7 [# `7 h1 x1 _ }
3 U' s8 q- i. F& Y! E
2 o: b9 b" t7 N8 E3 Z) Y z SetCursor(hCursor); : H, A* R) o# d8 k7 y; f: J
return TRUE;
+ g9 v3 K" E7 P6 y% n- x}
* r8 o/ } n# Fcatch (TCHAR * pszError)( E0 V0 O2 E Y# i3 D1 t g
{
, }! T7 e: ?. V3 W' e. R0 ~* h SetCursor(hCursor);
" E3 A" S& P3 L* i+ F) o ::MessageBox(NULL,
1 @2 Q; V5 |! F/ Y/ Q. z# @! D pszError,
! p8 O: A+ O% f _T("提示"),
9 Y( n: ?* Z. o( R$ E p MB_OK);
: j! D. h, r; H$ g" F$ J% ?5 q if (NULL != lpszMsg)# T5 N" t% w! ~, i1 }; c
{
/ |/ T H3 j2 y2 {/ X% r LocalFree((HLOCAL)lpszMsg);
# ?5 H% Z V y; ^: D: j }
; w3 r# } Y5 o return FALSE;
6 g* C, }4 p6 L' y}
2 b' p/ R- E" q+ h}: I/ k/ O: v% |6 W! ^
$ j1 n; j, Q0 s8 g6 Y// 这些设备的启用和禁用主要有此函数实现2 |$ W0 h6 E+ S
// 参数说明,nStatus 可取3个值,-1 :啥也不做& i E6 ? D) |( |$ @6 @" ^6 X
// 0 禁用设备,1启用设备。
2 H' _6 U& @& J4 V// nIndex用于控制是对光驱,软驱还是对USB启用或禁用7 t' T( R# U0 e$ |8 V @: n
// 也是可取3个值,0 代表软驱,1 代表光驱
, f" F3 Y0 h' u% Y2 b// 2 代表USB/ O2 H( @4 X) o- G W3 E
// 譬如要对光驱实现禁用,可以这样调用此函数
5 y5 ^2 U7 s" i/ ^// ControlDisk(0, 1);2 w) m" V3 E2 ~- _' l i
BOOL ControlDisk(int nStatus, int nIndex)4 r$ p$ D) M- x4 P
{3 F* D) u) R7 k$ h$ x: `
if (-1 == nStatus)
! ^0 f1 Y1 h- b. B{' q" ?' @: I/ _0 I/ ^: }8 X* Z
return FALSE;/ R' B/ g$ B- ]& ]
}
$ z0 L# i: I3 S8 T* o1 m" f4 r6 d
" b- p$ ^8 P1 hLPTSTR lpszMsg = NULL;
8 A- o: c! y7 |/ Btry
( r. A, `+ D- {3 j1 j{
9 {2 z0 c7 z1 m) e8 g TCHAR * GUIDString = NULL;6 T( E$ L5 n$ w: L; g% L7 I
GUID guid;& R4 q2 Q+ ?! ]/ }% b4 x) [
ZeroMemory(&guid, sizeof(GUID));7 V- G% q" F6 F; @! U2 r3 o
switch(nIndex)2 X1 G z8 p \ Z! z
{9 S( U- O0 \& o, \5 M8 L
case 0: // 0 代表软驱
: {& Z1 ^, x$ x: j) z GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
9 I) |9 T6 w- } UuidFromString((unsigned char *)GUIDString, &guid); y) t' d, H$ i3 R
break;
' Z8 m+ j1 I; }- }9 Z; D' m case 1: // 1 代表光驱 ( ^/ c0 N( s! k% i
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");" q4 `: E7 D" c3 Q; F
UuidFromString((unsigned char *)GUIDString, &guid);
, k3 R6 ]/ n* c- q( B" w break;
' d% u7 m( p% L0 { case 2: // 2 代表USB8 t5 ]# M( i( N" E
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");1 S# a" o$ w/ ]$ c0 C- d
UuidFromString((unsigned char *)GUIDString, &guid);
4 g+ [( I0 p: S break;* X6 G m! Y- A0 D% e
}
# ]5 A! o6 Z$ _, J2 b( O: s* F7 C l& r# E
hDevInfo = SetupDiGetClassDevs(&guid, q _$ J) W5 D4 l
NULL,2 K5 ^5 i' l7 u7 u% _* M
NULL,
1 u6 v% y* T1 }. y4 Z2 N, c DIGCF_PRESENT);+ q4 x, C% |3 z: W9 g( M
if (INVALID_HANDLE_VALUE == hDevInfo)
9 y, t- T, R+ B! w1 ? {0 o, I$ W* ?( e' }/ @/ r0 j* f
FormatMSG(GetLastError(), &lpszMsg);
, o# e. |1 t( f) w r3 p( A! d throw lpszMsg;
$ F3 L! C# F* u1 Y o+ Y }
. ^6 |' A' W' D$ b6 ^1 c1 }4 I+ U) k. s9 O
DWORD i;, e, e# N: d! S7 Y
SP_DEVINFO_DATA DeviceInfoData;2 g* G4 Y4 k7 h$ v
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
: l/ N; ]# R! h! {( l% o( L) x DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);: C$ O/ }% U: g7 X2 {, p
) w/ P2 b0 H7 | for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)2 S; y/ b; [5 m7 ` r
{0 e$ \) U& ~, ?
if (1 == nStatus)
4 N$ L5 ^9 p7 N P6 X- ]+ G {. v$ Q. O+ z( `; `- @! @2 C( `
StateChange(DICS_ENABLE, i, hDevInfo);
, x/ R& ~0 s+ ]- L }
4 B. j3 v7 ]3 A; ?7 O" y% D else if (0 == nStatus)
) z* p2 C" U4 U, e {6 E) F4 f' c! a7 w7 T& Z( F0 h
StateChange(DICS_DISABLE, i, hDevInfo);
, [# h" {/ |0 E$ W7 ^) }% m2 x4 W, R2 m }
V& o% M" e3 T( Q }4 `0 G9 ^5 J! b4 _7 e
+ U! \! v$ }; a) P9 Z" B7 k // 释放 device information set
4 v* f1 W; q r* }- T return SetupDiDestroyDeviceInfoList(hDevInfo);
8 _9 |8 A/ @" l7 x# G}( s; l$ ~1 J5 y6 _
catch (TCHAR * pszError)
. x" K5 m9 U) ^6 Z. M" v: O{' g' O+ G% Y Y: C! U
::MessageBox(NULL,
4 U6 R& }. L2 w# q1 x- |2 _ pszError,4 i% `: E& Y6 Y7 T% A8 T; p& z
_T("提示"),4 v7 p1 [# z" R4 ?. u m
MB_OK);0 ?0 W+ d- p6 D, M& n% E9 i$ _
if (NULL != lpszMsg)! M) i3 J. ?9 A g
{
% Z5 P5 f/ n6 ?7 O" W* ~1 } LocalFree((HLOCAL)lpszMsg);, S- b0 z' w0 J$ U/ @4 B$ e" N2 Z
} $ U) i$ U& {9 R2 h! D6 I* [
return FALSE;) d" h* t" `6 }) H# W4 h0 n
}3 `6 A: x6 A' q( ~; I) y- w$ f
return FALSE;
0 J! t8 d1 _1 o5 o: Q' ^}* d* a' N4 [% K& {1 I& D+ g/ h" m
) E8 L' C+ ?& E4 M9 ^$ H8 X: Q
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
! O+ B8 X& o/ r/ l4 Q, ]" w& | 据我观察,在注册表的此项下下:6 \. U W+ j/ I" U5 i9 p j( _1 F3 Y
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\8 q9 R5 e* |& u( }# p2 Y
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
7 @' z9 w" I5 E& |# F. g4 b& Y+ [ {36FC9E60-C465-11CF-8056-444553540000}- N4 S) ~5 l# a) h0 `( j8 y1 |
这个是CDROM的9 Q" b( Y6 G/ ^+ d( K
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
+ D, V( w# N% [- W这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|