|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)
, s& L& I2 V3 L3 }: S4 x. f+ R! e; ~1 f- c1 L0 R
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
: w# T2 |2 @/ g g// 必要的头文件和要链接的LIB文件. W& m# g0 t U- s0 x4 J
#include <setupapi.h>
: x9 A' l) E/ u4 o#include <shlwapi.h>/ p6 J* `5 O. D3 K
#pragma comment(lib, "setupapi.lib")# Y1 F6 l" `6 F* C ]/ d0 l
#pragma comment(lib, "shlwapi.lib")
4 y4 m) G, }! _* J9 V) c
2 U1 J+ o. N6 ^' j5 _// device information set(我把它译为设备信息集)/ n8 _+ p4 M# h: J
HDEVINFO hDevInfo = NULL;
. o3 ?$ A8 _2 S/ y; |3 L- I! n, K& Q) z4 k, |
// 出错信息
( E! C0 j8 r9 K& g$ yvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)( l/ K3 C' C! y! `3 \; F
{ , p, ~1 X1 Z# ~* `" d
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
: d/ S7 K* b+ H0 N' z! b- ? | FORMAT_MESSAGE_ALLOCATE_BUFFER,
j ?5 x# d' m3 I NULL,
: V: S2 v" ?/ A- z2 a$ ]" k8 v dwError,
9 n4 [ [1 r* `: V5 X0 G MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),1 U9 Y0 F* a2 W" k0 |" j
(LPTSTR)lpszMsg,
, N; |9 V" o( h( O 0,( b( c! B; \/ ?' y; _8 W) P T
NULL);5 _! a7 `7 ?: A) ^& ?
3 h, d# q0 B: g! ~6 n
if (!bOk)) y9 I* a1 e* W- w: p( N' N& n
{) n% P7 M3 q" a7 E/ |8 r# d# i5 S
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
A9 q, q$ c( p5 j) P8 f! \ NULL,0 ?! c# [1 m- N2 a2 M; [/ [
DONT_RESOLVE_DLL_REFERENCES);
' J1 _+ Q2 p, x" L& b if (NULL != hDll)# }1 ?" N& C( \1 I( i" }3 g/ t
{
. j: Z! J" q/ @) x# O6 }$ n7 [! Z FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
* A1 d# D' _* Y- m5 D3 i FORMAT_MESSAGE_FROM_SYSTEM,* q# w4 U+ T0 {" p2 I0 A
hDll,
! e0 [0 O# k! ^, T dwError, K& q6 z& l* Z
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
4 U$ R) h9 n( p3 V( ?! [ (LPTSTR)lpszMsg,
" I9 b* w% ^$ S( ~; P 0,0 _( I) I0 K- Z
NULL);
9 b: P# o- q4 J( Y FreeLibrary(hDll);' w; }4 X# m9 `+ T! P& C
}+ }& @2 M' O- ^; i# |( s
}
* A- h# {+ x# \2 Y}
( U- Y6 s! T3 l
8 n* d- m( l: ~7 E- {) B$ DBOOL ChangeStatus(DWORD NewStatus,
$ F% Q7 h: Y# @0 v. ?0 q, i3 w" q9 D DWORD SelectedItem, . |( m0 i; B7 I
HDEVINFO hDevInfo)
. F W+ Y( i' Q! ]/ O7 F' H{
0 f, I" n/ F% \3 P. X" kLPTSTR lpszMsg = NULL;
2 \5 \0 U& H) ~; X' N1 ^; {HCURSOR hCursor = NULL;: J" L: x2 ^# r5 h7 z
try; N- i% |1 n' H. s* h% k
{- N6 _+ k! ^) _0 ^. K$ a' G
SP_PROPCHANGE_PARAMS PropChangeParams = * m$ k4 ?* e: x
{sizeof(SP_CLASSINSTALL_HEADER)};) k0 C9 c) y6 @; v
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; & @0 P# o* ?& d: a' s3 X. V
7 ^8 C3 a6 n4 a0 Z hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));! z5 L6 ~) M: M. t* a2 J7 b
% r9 \% P. H$ Y$ j) W" g
// Get a handle to the Selected Item.- E; m; k8 J1 \$ N- p' {7 U
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
& k8 F* ~7 H6 m! i {/ V X, S. U" q# Y
FormatMSG(GetLastError(), &lpszMsg);
" D! t( j3 ]% i, w1 e7 m, [ throw lpszMsg;5 F" ~/ e# k! A/ P0 _- j3 T% a4 g
}
7 }; Q5 c$ m, K. T' F; |% ^+ _$ o( z* A( j# }
// Set the PropChangeParams structure." x. W( b1 e' e" @
PropChangeParams.ClassInstallHeader.InstallFunction =
' Y1 V) _ n" O9 t! M DIF_PROPERTYCHANGE;
- N7 q ]1 K; w! v PropChangeParams.Scope = DICS_FLAG_GLOBAL;
2 t, a1 M! j! o( A6 O PropChangeParams.StateChange = NewStatus;& _- P3 s7 X' E: ]8 ]5 T& \1 p* H
3 }8 m7 p$ _; P. U, j8 I8 ?6 Q if (!SetupDiSetClassInstallParams(hDevInfo,
1 _4 j1 f0 f$ j" R# E8 H: T' P2 g &DeviceInfoData,
- ~/ w3 p. x- t8 l (SP_CLASSINSTALL_HEADER *)& ropChangeParams,
& H8 ]. M8 @9 I& c8 A( A sizeof(PropChangeParams)))
! s1 {. Z! M1 ?1 L {
* D$ m1 r- B% f4 ]3 W FormatMSG(GetLastError(), &lpszMsg);
0 ]( a3 i4 C1 W6 ^ throw lpszMsg;
, |2 C8 s# w/ L+ B$ B- ? }" t, G9 q9 C& n
' {7 n5 v. I3 T: w4 R8 r
// Call the ClassInstaller and perform the change.
7 l3 B i; G* F o% t if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,7 }9 A5 j0 O* {" y: z9 |5 a7 X
hDevInfo," x5 y0 d6 l" r: U0 a
&DeviceInfoData))9 v2 W& P8 p! b4 f `' j6 U; k
{
L, |" Q+ V0 k* m2 f |/ m- B FormatMSG(GetLastError(), &lpszMsg);% t8 Y* x M6 T$ A1 t. z
throw lpszMsg;# {6 k6 u5 d. n Z. @+ U
}
+ F* p0 i# q; s( r& @. u1 A& ^' r* ~0 j/ [
SetCursor(hCursor);
8 G! L2 P8 D2 T8 R return TRUE;% R2 u' T* E* o/ k, |) H
}
0 w& v! [+ y% @% a/ s, y2 @catch (TCHAR * pszError). ^ e& \3 g+ }+ f$ ]0 J! V$ b7 J) i
{
; ~0 X4 y/ k$ O& q SetCursor(hCursor);( g4 ?/ \8 U- S7 G& n: b
::MessageBox(NULL,
4 d4 \$ u9 V, V9 \$ T pszError,
, j+ y! G' }/ s _T("提示"),6 Y7 F! t- t' d/ N W/ w! f
MB_OK);* i- w1 d+ E+ S
if (NULL != lpszMsg)
2 K1 g6 g& p; I {
" o- u( P1 k5 ^) C( p$ y1 R LocalFree((HLOCAL)lpszMsg);
3 V' M( j9 {0 K' y4 X" O5 @) s }
Z: l4 t/ u, c A0 Z return FALSE;3 f* j; B; q# ^8 W
}
2 Q- h% A/ j7 n}
1 o/ t8 s8 _( I) H0 e; J/ R- l. A! ?. a+ |# W# ~
// 这些设备的启用和禁用主要有此函数实现' \( E! G* y% p/ z) k, g8 o5 M
// 参数说明,nStatus 可取3个值,-1 :啥也不做 X6 k+ ^& |. H. b& B" y! c
// 0 禁用设备,1启用设备。
7 E. r1 N5 @( K6 d: y// nIndex用于控制是对光驱,软驱还是对USB启用或禁用 I6 |+ A& Y. Q& j+ h3 y {
// 也是可取3个值,0 代表软驱,1 代表光驱6 y8 W" a( F5 z# Y( Q- ]$ h/ e
// 2 代表USB
2 X" B% Z" m0 p; e6 `0 y// 譬如要对光驱实现禁用,可以这样调用此函数
) M2 t/ K6 U/ H) l5 U% I// ControlDisk(0, 1);
7 _5 ^9 ^2 a- [+ e, G; ]BOOL ControlDisk(int nStatus, int nIndex): s; ^$ w4 E" {/ D; S1 ?4 f/ m
{' _, h6 `8 D) h) i
if (-1 == nStatus)
) l1 w' v( O9 W; N{7 q7 N: b9 b; {$ f2 F
return FALSE;. i" H/ i" u$ C
}
# p7 M: t) k: q$ K2 R
( Y8 w% @- r$ J/ hLPTSTR lpszMsg = NULL;; S% c2 f7 f# T4 B+ C, Z: k) n
try" v" ]& w; R5 ^2 p6 e" @
{
2 `* s' w5 H5 f2 _3 z$ z TCHAR * GUIDString = NULL;
- s% A. u2 e6 Q8 `' s; _ GUID guid;* b0 F# A( ?+ x' M$ V
ZeroMemory(&guid, sizeof(GUID));
3 Q. ~% B( D/ @+ F! ^/ R switch(nIndex)
* S6 R4 U. J1 } {
c# {% G/ F9 Z+ |! K case 0: // 0 代表软驱
2 }( K7 V8 C4 B7 V3 z! i GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");! ]/ P2 s5 F M$ M0 D% d2 s& h, i
UuidFromString((unsigned char *)GUIDString, &guid);
- }) t; w; f/ G6 w3 M break; 6 K* L ^5 I/ d
case 1: // 1 代表光驱
' Z6 e& j* Q' u GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");' q7 L7 o+ S( i
UuidFromString((unsigned char *)GUIDString, &guid);
' Q* t" F8 |% l8 Y& y break;
1 v4 L) ^ J# h case 2: // 2 代表USB
# }, W3 j* w* C K6 {9 u9 ~" j1 a S. y( C GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");0 U$ X1 c8 o1 U/ {
UuidFromString((unsigned char *)GUIDString, &guid);
* B+ v* k4 Z& K( n7 l9 p8 [ break;
K: G( |1 m" D4 n }/ R7 g3 y% E7 T0 m! y) b8 E
/ v. q' o7 K0 i8 _7 |/ L, _4 b- m
hDevInfo = SetupDiGetClassDevs(&guid,
& V# r% m, ]- [0 y" Q3 w) Q. B NULL,
! ?! C7 @2 F+ k6 D% P5 L9 w8 \0 u NULL,
( g, V$ T! ?" D# M6 i DIGCF_PRESENT);0 M4 G( S! o8 u e
if (INVALID_HANDLE_VALUE == hDevInfo)
% e& N, s1 _$ T {
! t' j1 a: z$ n. v l; ^- D e1 A FormatMSG(GetLastError(), &lpszMsg);+ |% e' J+ B+ I1 l
throw lpszMsg;3 r8 J( X$ s' J. ~/ G
}$ A1 I1 {2 a+ H+ X- _# K
& W! x: }# S2 ]8 V, v
DWORD i;
, @/ ]& _" Y$ i7 g# j8 f$ V" D4 l SP_DEVINFO_DATA DeviceInfoData;
( V p$ q& y) ]7 D8 w7 w2 \, o3 L9 Q1 n ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
}) l4 N) C, {5 [& K DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
% v/ a. m! M6 ] r, [
3 h! ?6 v1 |5 ?- c for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)$ p5 G n8 k5 J7 [% y
{2 e) q$ a, i- T# n+ v$ |8 o
if (1 == nStatus)6 B7 G1 t$ V H5 G! P" n- w/ E$ o: v6 k
{/ X" f3 ^3 f4 \. a) B3 }- J
StateChange(DICS_ENABLE, i, hDevInfo);% d8 M( J' [- d
}3 C U! I$ Y$ F' D
else if (0 == nStatus)
7 T6 [0 m8 ^1 Y+ d {' a5 {) n; K( a
StateChange(DICS_DISABLE, i, hDevInfo);4 g! z6 A9 W5 P0 b" Z* p% O
} % |% `) l% N; J) N
} R4 j( m0 c# e3 O4 @3 j
# W4 S" s) O" K: O" T1 x/ x
// 释放 device information set+ W2 ~3 p* q# e: e8 i7 d
return SetupDiDestroyDeviceInfoList(hDevInfo);
5 C2 N( I# e M% c: [8 G( ~8 s}$ G; n& Q8 X( X+ f& N3 J, a
catch (TCHAR * pszError)' x" O9 E" r& c# \+ s3 x9 Y
{% x6 Z7 r+ S* H5 s- Y" L8 x4 ~/ n
::MessageBox(NULL,
5 w$ \$ r; E |* i pszError,0 t* i% K/ I& z. p# X2 \: h" w
_T("提示"),
& W% e# g7 p( P' E: ^4 [: C MB_OK);
5 ?- P! ?. {6 r' l3 Q if (NULL != lpszMsg)! V d! P( u% g8 M6 s. e8 U
{
: l+ ~' x4 {7 r# ^; `/ B, } LocalFree((HLOCAL)lpszMsg);2 R% L9 Z* b: M7 g7 l
} $ F& V7 h a" q
return FALSE;$ A, Y4 M' v" u* Q
}
" _5 W' Z' ]0 T" Yreturn FALSE;
/ F( K/ w6 H. N' _. Q8 T% I}
% e0 T. h$ }8 ^
0 M! }+ x1 j/ {& n 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
; ]4 x# h! z' X$ n 据我观察,在注册表的此项下下:% d$ ^/ | e, u
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
& G% r7 R% q$ a% z3 a; [ 有很多GUID,每个GUID代表一个设备,譬如这个是USB的5 G' i: h$ }' I
{36FC9E60-C465-11CF-8056-444553540000}% a5 K' K% v# o' T- f3 o
这个是CDROM的
* e \* V7 i" i8 J2 h {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
2 e' h0 b6 t! `% x! s6 k这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|