|
(dlutyuanhongl发表于2005-3-15 23:14:04)- {, m: n" a, \# @1 X# t" T" R
; `. b5 E6 G( j9 U
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:: p: {+ e' N" H" ~
// 必要的头文件和要链接的LIB文件
0 t9 t) ~) u2 M; K' s, `#include <setupapi.h>
. X' I8 o) w' k% G; Y. T#include <shlwapi.h>% v$ [2 u2 O5 b# P+ [3 y T
#pragma comment(lib, "setupapi.lib")
9 M- S* d1 v! n1 |' t2 ~#pragma comment(lib, "shlwapi.lib"). b1 ^+ v* z$ q. @! x% o, e. [
u! t* S" w+ c5 H8 t
// device information set(我把它译为设备信息集)) N$ E. j* i9 D* J- J# s" m
HDEVINFO hDevInfo = NULL;6 Q0 h ^' `7 V6 G$ L/ s
/ Y5 z! T5 C+ }7 d" j/ y" O
// 出错信息
: D& a. I9 Q! S3 w' Xvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg): k) z3 t" m) ]3 M. |- D
{
+ U! U7 Z! q8 x1 ?3 s BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 0 v. t8 |7 i4 U2 v7 |( `3 V1 \
| FORMAT_MESSAGE_ALLOCATE_BUFFER,4 y0 S. Q) \! H1 M4 P
NULL,) C/ M( ^. @) }' W# y
dwError,1 E0 O& v1 m0 K/ _% ^
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
& f% V; N( F6 q# @9 K& I (LPTSTR)lpszMsg,# P0 |4 S- c; K; U9 e( F) l
0,& d2 A$ N! O1 R
NULL);6 E7 r+ @7 ]0 v# }
5 L7 T7 k3 s g, {( n
if (!bOk)7 X1 B5 x$ R9 N! {+ C9 }
{
, {2 G6 a4 \+ ~ HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),9 H. p( {8 T) V8 V! [5 p- m4 l; `; B
NULL,) ] U- E4 A; {5 W- \7 z M4 @
DONT_RESOLVE_DLL_REFERENCES);' }, @; @, {, D5 P1 A
if (NULL != hDll): \: _+ }% e- ~
{
4 Z! R; M% R4 ?9 Y# C) U; Z% S! ^ FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
" }( N/ j% T$ k2 ^/ e# l" m FORMAT_MESSAGE_FROM_SYSTEM,/ B2 R9 p1 D, V4 z4 I! v
hDll,
% ^$ g4 i6 B) A+ \0 }% F* B: y: Y dwError,5 n8 P1 s: ^; ~7 T* I# `" u
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
A& B+ N4 U4 ], Z& }" ` (LPTSTR)lpszMsg,& ?2 O$ L$ z7 K6 y8 X4 }
0,4 ` b/ z( ?+ }- Q) k) t
NULL);- K. g% K' Z) T( X
FreeLibrary(hDll);
1 s) I8 u5 T/ w* a6 U }
7 X D1 g3 w; n& T" n% v) V: P} A0 W- @2 T' j n0 w
}
0 B% |' K0 i! Q1 \6 K, @- [5 [ B! f. s
BOOL ChangeStatus(DWORD NewStatus, # n/ o ^9 o6 K6 i
DWORD SelectedItem, : W b; T4 P& O9 u4 w% K8 Q1 k6 o
HDEVINFO hDevInfo)
& ^+ J. ^ [6 q9 n! |# K2 O; {6 y{
$ v; F! j0 P9 x% d0 wLPTSTR lpszMsg = NULL;
. T/ J- h# H9 v& b& ^0 ^ gHCURSOR hCursor = NULL;
. L% P# j+ V0 ?4 X c6 @( Dtry4 d6 ~/ m G$ {) ?) k Y
{
+ T2 |! J9 ]/ }2 } SP_PROPCHANGE_PARAMS PropChangeParams =
F! g" C0 W+ i4 ~1 t {sizeof(SP_CLASSINSTALL_HEADER)};
8 W6 {5 A) v. N: A! W/ H. f$ t SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
3 u# z6 N$ }+ m, N
1 d. Y D4 y' q! ~9 o hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
) g+ E/ w p. Y0 U* W* H! f& U: R. P, B4 j8 d9 X) g$ ?9 Q0 c' e
// Get a handle to the Selected Item.# V& h- }8 f; W- F; |1 G+ G
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))+ G! P' ^0 a: ^4 h
{
. G% b" D6 J8 ]/ Z+ p1 L: W FormatMSG(GetLastError(), &lpszMsg);. s; ~8 c' b P5 R
throw lpszMsg;
6 _) r. p* S. c }2 v1 v+ @! M( p `- T X
' I9 y' J$ y/ s% Q" f
// Set the PropChangeParams structure.
/ b1 ^& X" Q8 g4 U PropChangeParams.ClassInstallHeader.InstallFunction =
. P. _- M$ V8 Q$ E/ C2 e0 J0 S DIF_PROPERTYCHANGE;
6 j, {( }& G% `0 s0 s: J0 F; s- P PropChangeParams.Scope = DICS_FLAG_GLOBAL;
9 p' R2 {0 W% _! { PropChangeParams.StateChange = NewStatus;
6 s, {) A; i4 W. w9 Y7 I& u! @7 e1 `
if (!SetupDiSetClassInstallParams(hDevInfo,
+ h Q F$ R* M* r3 h &DeviceInfoData,' m1 ^' q! A/ s! @0 [
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
" y" v: n6 z( e- [ sizeof(PropChangeParams)))
2 y% i* E! y0 C* [+ ] {5 Q* |1 Z0 H+ l( b$ }. ^9 ?
FormatMSG(GetLastError(), &lpszMsg);. W7 `& t* v; B. F0 k& l* g, V3 U
throw lpszMsg;8 D7 u+ [ ?% a7 M! Q+ w4 M
}
- w# ] c; v8 F
' f. I4 B- P0 v/ k# i! o$ y // Call the ClassInstaller and perform the change.# N0 b# a' ]2 l) W/ X# Y. g, W
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,& `" h8 P- f& d1 R7 i0 h
hDevInfo,
& K/ {& R6 P& |) h2 `& @ &DeviceInfoData))8 A; s" @, g* L. V% Q
{2 C6 S8 v& \/ Y- b+ r7 Y
FormatMSG(GetLastError(), &lpszMsg);% c+ m" Q+ ?' v! i: D% {# E2 Z& U
throw lpszMsg;
6 K" }/ P, j0 u! a }% ?( T. }! u- J/ P
" _& J! M1 d) q8 E SetCursor(hCursor);
+ f3 d; l# _. _& D \4 O return TRUE;. c4 |. b6 D& n0 f6 W" z
}
5 @/ d- {$ P b+ u' L }catch (TCHAR * pszError)5 r, L) W8 _2 H1 k3 m
{
( ?& F4 P. i; @$ t- t: z SetCursor(hCursor);
1 z6 c! |! m: x+ A1 z' ^ ::MessageBox(NULL,
9 B0 s8 ~' o% u1 S2 `2 T9 w pszError,8 [% C3 p! e) h* d/ r1 P7 \6 i
_T("提示"), ^7 o7 I1 H0 w+ I0 g( v9 h1 r6 I
MB_OK);
& q+ U% F1 K' Q- P" @. S7 ~4 T if (NULL != lpszMsg)
( V7 ]6 @# M7 Q, n: X {8 P7 B8 b3 `" V7 s5 _
LocalFree((HLOCAL)lpszMsg);* I [' p8 f! {+ t" [# [- V0 I5 Y
} 5 g+ w* h; v# |0 e
return FALSE;! ?5 L- J, g- A6 D+ u4 A! X
} & Q+ p0 G5 K$ c4 Z/ w
}& a* p5 f1 z1 o% N
+ T: N& l8 v3 h5 b" e8 G7 H// 这些设备的启用和禁用主要有此函数实现
# e: l* y5 O! T5 }. g/ H0 W// 参数说明,nStatus 可取3个值,-1 :啥也不做
* Z- u5 I6 }) W* S5 a' {// 0 禁用设备,1启用设备。
/ g8 R2 e( q B! Y. h// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
: i5 x; z% ~) |& }* T% N1 A. k// 也是可取3个值,0 代表软驱,1 代表光驱' a3 \# @5 g* o& T3 B! Y
// 2 代表USB6 G3 O0 i4 j) ? Q/ T
// 譬如要对光驱实现禁用,可以这样调用此函数
+ A/ d/ Z0 P" M// ControlDisk(0, 1);
/ W) _2 R. ^! p0 [: QBOOL ControlDisk(int nStatus, int nIndex)8 s0 T( K. j- X' B0 }
{' C, T" L# J7 `0 o1 I* a \# I, f
if (-1 == nStatus); d2 u- y6 a6 S0 _% R
{8 F/ I" ^: N! f$ F1 m3 z: H
return FALSE;
( T% u8 s4 G0 \) E X} & d% e' F) g; m
' r: m; D9 Z/ Y* H! nLPTSTR lpszMsg = NULL;
6 T7 d- t/ D- s+ M$ ?: utry
7 y5 F* o4 U7 N$ T7 x{
: x0 F6 G$ B7 m* a6 b TCHAR * GUIDString = NULL;
0 a( E' E2 U8 ^! d# t GUID guid;
" k" P( b1 ?' Z- j3 N t& c# F2 p ZeroMemory(&guid, sizeof(GUID));: |" `; a9 q* V0 e }! Z# m0 G
switch(nIndex)3 k! Y! i, z) j8 e$ ^
{, B5 O) h# }' f$ J) g# G. a7 ~
case 0: // 0 代表软驱+ g* I6 {, }6 G4 A
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");4 m& d0 ]6 F3 u# i; D) m
UuidFromString((unsigned char *)GUIDString, &guid);
( ^' h4 T* ^* [' e break;
: m. |! {2 S p7 _# u! r1 J, ~ case 1: // 1 代表光驱 6 \2 x; G5 \, x1 `3 y
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");* ?4 r ]7 v- I5 v2 g& C; m/ H% q
UuidFromString((unsigned char *)GUIDString, &guid);
& G5 R$ [* n0 C y$ x( F8 b' C break;; ?% B z2 @$ g) L( \( G
case 2: // 2 代表USB
/ F/ m9 p1 G8 S" f0 [$ D0 v9 t% n# `+ m GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");% O1 W; U9 \5 O( g
UuidFromString((unsigned char *)GUIDString, &guid);
$ J( D: Z% m& C8 ^* y2 I break;
/ {" E( Y: ?: S+ c, F+ V2 k }
" S6 h: f5 v! T7 |
! R" F" S9 W& ^. Q# Q; n; z$ ~ hDevInfo = SetupDiGetClassDevs(&guid,
* }( E4 _6 E3 P! I NULL,
+ t( j8 F1 p* W) U NULL,6 Y, S( M% B3 R- T$ b
DIGCF_PRESENT);
! W( Q$ _/ R1 [1 ]9 [6 H0 j if (INVALID_HANDLE_VALUE == hDevInfo)
" D- L) ?6 F9 B+ @7 D$ }* Y {( S! ?% ?7 E: C$ ~: L
FormatMSG(GetLastError(), &lpszMsg);" U7 B& X" k7 [3 w
throw lpszMsg;
) |' z ]0 O8 E1 ~8 Z }
; y) q) x5 t0 g: i# U7 R1 c6 n
, B! b- ^* }2 }- v% b DWORD i;- M X: j& c; R) I r/ B" P
SP_DEVINFO_DATA DeviceInfoData;
2 n- g1 `) `& T K+ p' f6 r1 L# {( h ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));* ~9 y' ^0 E8 J1 e' F; U
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);1 y, X& i% s& K0 `# O0 A6 B
5 P% L1 E5 I; A. _ for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)3 B- [# K9 `. A: @
{
* c4 [- g6 K- E if (1 == nStatus)7 u. o6 `4 d+ i A4 k& e/ W6 G
{! k/ T0 u6 n- j. R) L$ N4 q
StateChange(DICS_ENABLE, i, hDevInfo);
# w2 o" C8 X6 r8 w }
" {4 f0 F' i: z2 Y% m5 k- I else if (0 == nStatus)
7 O2 ~( T5 S; U- n3 r2 D+ b {% Z7 m6 n O8 U- P8 s( }) E; W
StateChange(DICS_DISABLE, i, hDevInfo);
" H J4 _/ [# A2 H8 c6 @) W }
) \( l5 ^! b! \ }1 ~+ ~2 K; k8 C5 K# t! m& k
$ c9 T. Z8 D- _; H! a // 释放 device information set
1 F2 {* c/ n+ K/ \* ]: M* y return SetupDiDestroyDeviceInfoList(hDevInfo);$ O& ~) \ ^9 d
}+ r2 t3 U$ D7 i# o
catch (TCHAR * pszError)
! T0 _$ h6 v/ Y7 o{/ f* @& {) f' A( F9 V& ~# L
::MessageBox(NULL,
( X$ O: K1 U& O pszError,; v* \7 V+ ` C/ S7 ] ]5 l' d! H
_T("提示"),
! D; Y- }6 d7 {( Y/ p MB_OK);/ d3 W* Y2 Z- J% m2 h% S" |
if (NULL != lpszMsg)
2 n8 ?. N9 h; K7 x- b, ] {" [7 u& {" q1 }0 K9 l1 h: I
LocalFree((HLOCAL)lpszMsg);, W @3 V& \6 F B, ~3 w- |
}
% O( p; R6 A/ h9 h return FALSE;
, W: {7 v, D: p) }1 Q, w. U}4 N5 u1 ^- I+ Y& |$ T" m
return FALSE;* X. f, U9 {& y
}
$ l' I/ I5 ?3 l; o' T6 j" U1 \1 J0 z4 K+ \ m
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。8 ?. q9 f! k4 p9 m( T! ~: f. R
据我观察,在注册表的此项下下:9 S4 m6 |% D9 b! Y, ?
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\/ I2 A& Y# e8 n0 ^8 g
有很多GUID,每个GUID代表一个设备,譬如这个是USB的: P( K p5 H$ P- |( d- @* `0 @+ g
{36FC9E60-C465-11CF-8056-444553540000}
. A8 U5 f8 b% Z u7 F r# y* ~" ~ 这个是CDROM的
1 |5 H2 v6 n- a4 u& B, E {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。, Q* I+ s- G2 {) H
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|