|
(dlutyuanhongl发表于2005-3-15 23:14:04)
5 \. F" J7 Z9 W
8 _* W$ c$ }1 E S1 \6 x0 }- I这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:3 `0 t0 \; U7 o4 ]
// 必要的头文件和要链接的LIB文件2 Q, T9 ^: U4 w: d2 l- [' z3 @
#include <setupapi.h>* e9 G$ g& H' Q! t8 q: v' M# ?
#include <shlwapi.h>
( K3 ?1 f) A5 ]$ W" [#pragma comment(lib, "setupapi.lib")
; v; z$ F* Q& X% l& z: e#pragma comment(lib, "shlwapi.lib")! Q7 E' `4 H; `/ X& @
8 T+ b: |8 w) V4 | R$ b
// device information set(我把它译为设备信息集)
) m) {' s; r0 ?& S2 v: K$ j& IHDEVINFO hDevInfo = NULL;' f7 ?1 \; V' Q5 c! p
2 b# P+ V! h$ `$ V* f! G' V. H. O0 n
// 出错信息
0 F+ ^8 |. ^$ v' E" |/ Zvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
, H* k, y! W) J: R{
6 z5 b% i; E/ B2 g, k9 ^ BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
# C! T6 S) y8 ~$ A' C1 k) L, a6 \ | FORMAT_MESSAGE_ALLOCATE_BUFFER,7 j8 U. @+ T/ H+ u( f" Q
NULL,: H. Q- [5 ]6 t$ R) I* \
dwError,
% j0 d: e' |$ W9 w% `- e8 C MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),* I+ s& u1 g( x, |5 f9 ?* M }7 M4 {
(LPTSTR)lpszMsg,8 v1 F1 W/ y7 U0 ~/ H# m$ x q
0,1 Q5 k3 j8 p' \" m) L# F
NULL);
% z; _1 ]- N+ ^7 f
4 J0 M" }% X. |4 bif (!bOk)
0 F' X% \4 t) V; \ P* K{
, s, Z" ~& c4 X- k$ a" [ HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
1 {. y, R6 J+ g8 w, [2 L/ y, G NULL,7 Y% G }: `4 f8 o) D
DONT_RESOLVE_DLL_REFERENCES);
! W7 D2 R6 b Z/ `. T0 Q if (NULL != hDll)
/ X$ Y) ^# \) @$ g- a4 c4 t; U {
# V; B# I# R0 ?0 n FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
' w- l5 j% e- G3 {' @) B: ?' F FORMAT_MESSAGE_FROM_SYSTEM,! P u3 Q6 s7 R. R7 _6 Z
hDll,% k5 B$ p1 u1 |& ~0 {; X
dwError,' w! b1 P) I q7 c8 V6 ?+ r8 W
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
6 {( W5 f1 f$ ] (LPTSTR)lpszMsg,
8 P) s# Y7 }. ]: w% M 0,5 E. S' i0 R% h; [2 l4 a# N
NULL);$ i% c% B3 e" a) f, V* i& _9 e
FreeLibrary(hDll); p4 r! X4 b3 t5 R
}- @' T2 O" z2 [: K% M3 v% L* t- K3 j ?* m
}
0 O* ]1 I3 }* A/ P2 s- w; P}' J: L" `3 t# e1 {! B8 s
- g7 k; t, z( v6 C# ^$ \BOOL ChangeStatus(DWORD NewStatus, 4 H+ q. X4 u3 _: |+ v, a
DWORD SelectedItem, 5 P6 S' ^9 R. d
HDEVINFO hDevInfo)4 n- I3 G* X; W! h$ f
{- o, B7 `9 A! J7 `" G7 F, B6 o
LPTSTR lpszMsg = NULL;6 O8 E" I) l% I5 S
HCURSOR hCursor = NULL;0 v6 R- _9 `4 |. o5 d* F7 S
try* F9 S/ z7 M: k7 G
{
& j$ B+ {5 Z$ b& D) D SP_PROPCHANGE_PARAMS PropChangeParams =
+ z* W2 T8 p2 K4 e5 X5 o {sizeof(SP_CLASSINSTALL_HEADER)};3 D' I9 Z# a0 h8 ^# x
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 1 A2 D* t+ a8 R6 }, E
" K- x+ j2 f0 m9 c0 M
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
" n. @( j! s# n6 z4 E
* w; x) m5 h; i& b5 X* @ // Get a handle to the Selected Item.
5 \# C' Z/ n, k, F' r, ^: d if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
( ^4 C2 n2 `. s, u) W {
$ a7 S8 x' d# E$ {$ g2 Y% R FormatMSG(GetLastError(), &lpszMsg);
- A' j( Y d, N& G, i throw lpszMsg;
$ m n; I! s. |4 i: ` }
2 R2 [: o, s6 w2 p1 f: [5 Z% F# T$ h* j4 h$ @8 o4 o( g
// Set the PropChangeParams structure." E7 _1 {& c# R7 r" d% }; G
PropChangeParams.ClassInstallHeader.InstallFunction =
# B( t8 X: x5 o" ^( d$ a DIF_PROPERTYCHANGE;+ X8 L1 {- @ g% M1 m
PropChangeParams.Scope = DICS_FLAG_GLOBAL;+ |3 s" a6 p/ d& |, @3 f( e
PropChangeParams.StateChange = NewStatus;
: x E6 R; J$ u3 y8 p5 R2 ^2 Q" H2 S: c# [: O5 m- Q
if (!SetupDiSetClassInstallParams(hDevInfo,1 y1 l! _& ~% m4 d3 ^. j# F, D
&DeviceInfoData,1 @9 r" _5 z( C, \) Z S
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
/ ?& b6 U5 y' g ?! Z3 E6 i sizeof(PropChangeParams)))
) E6 G) D8 n8 Z- j5 _0 W$ _* W! J {
. e& v, O) ^: f+ W9 u! ? FormatMSG(GetLastError(), &lpszMsg);( {) q2 B) z1 b5 @7 Y$ z9 a
throw lpszMsg;, O* i; z6 t$ y3 P! B" ?. N
}7 l* a- w! {5 B0 k7 N( h4 i
% i2 D [" W) C! P: D // Call the ClassInstaller and perform the change.
( n# v4 R6 z* A* n# j5 F Z% l if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,1 B) a& Y5 y# x1 y4 d. i. H# f
hDevInfo,6 l9 m' }1 Q. T2 E3 w( g# S
&DeviceInfoData))0 E! V/ L' @# W
{
. e" n" s$ {% `! f+ P FormatMSG(GetLastError(), &lpszMsg);
2 E: s& m1 e9 t+ L3 T3 X throw lpszMsg;; r/ S/ e* V" z2 ^; G
}
! d* t! j' o1 X1 T' S- J. h. R( v) _7 I; \4 H1 J+ Y# f3 [$ \
SetCursor(hCursor); 8 h' h+ {" W% K8 e7 |. z- `
return TRUE;
: D8 a. w8 N5 M7 x, ?( N}
! i: B! o/ o5 @' wcatch (TCHAR * pszError)
5 O1 Z: _/ l! e8 _8 _" J{: r* k8 P) T# H& k6 m) k4 l
SetCursor(hCursor);$ I! b! ~2 U" f5 I7 B
::MessageBox(NULL,
. c) P+ F4 |, [$ Q2 R8 Q pszError,7 U( k/ `- e1 E: K
_T("提示")," n1 J) D c# ] u
MB_OK);
! x6 s4 w5 z# a$ d if (NULL != lpszMsg)
: Y( K3 x) c S |2 V {
[: U3 O0 J1 u) y4 L( J; d LocalFree((HLOCAL)lpszMsg);
! M* W J3 E1 J, ~, { } - k! S0 y; t+ ~0 h( h
return FALSE;
/ ] N4 W( c. U% V# l9 P. S3 P}
6 Y$ C7 w1 t3 U}
* k8 F9 s$ |# a* e( L$ t' t' \: v* {& R; P. `
// 这些设备的启用和禁用主要有此函数实现
5 o# u0 u. z8 F3 A// 参数说明,nStatus 可取3个值,-1 :啥也不做
/ M+ o/ A! d( x9 }4 V// 0 禁用设备,1启用设备。
* I( g$ n) A* `& j1 j" C2 T// nIndex用于控制是对光驱,软驱还是对USB启用或禁用. L1 R: G& r$ u% j6 A
// 也是可取3个值,0 代表软驱,1 代表光驱% {2 w9 b% J Q2 t2 Q9 G" Q
// 2 代表USB4 C9 s) F" O$ I) P7 I
// 譬如要对光驱实现禁用,可以这样调用此函数
2 c2 ?8 G, B/ u1 L2 H9 i% Y// ControlDisk(0, 1);
- r' S' k+ N- N( zBOOL ControlDisk(int nStatus, int nIndex)9 r2 f, i- X; A/ p; h
{0 ?# K0 W" g. K) P1 S2 W8 ?) j" |
if (-1 == nStatus)6 O2 }, C, P* o
{
" U! y0 |, @& `8 q( c- E return FALSE;
+ K" V5 x: \ A3 i/ h7 j}
- C1 i# |1 p3 r1 H* n u. N6 @5 I
LPTSTR lpszMsg = NULL;
2 {/ J& U; } p5 ]& otry/ }9 [9 \+ S0 \/ L
{7 P9 @, J- p9 K! b9 n! c
TCHAR * GUIDString = NULL;
( Q2 _3 p2 R5 i5 G( _ GUID guid;
( [0 a) l6 b) w2 Q( E# } ZeroMemory(&guid, sizeof(GUID));
& I4 R! f3 {8 j; v0 d switch(nIndex)0 G! p! T" V. `0 m
{
4 Y0 y* U# r2 a4 n8 w. t case 0: // 0 代表软驱
* V9 _7 P1 S7 L1 A- f4 L5 Q- { GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
$ i$ d6 ~2 e+ [7 R# j7 V$ t, U( l UuidFromString((unsigned char *)GUIDString, &guid);
G% }% c3 a9 G; |1 E break; ! l1 R( p1 G$ e0 J- a w% |
case 1: // 1 代表光驱 P) p/ t0 T% j- F
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");) N& }- _% E4 ?; }9 W
UuidFromString((unsigned char *)GUIDString, &guid);
4 U5 w. N4 X% }2 q9 J' M break;
. F- y: w- g( C. G case 2: // 2 代表USB6 X* S9 @7 A* ~2 J; G4 B, u, E
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
$ e( R3 d/ D1 i; A0 ^! Z) v6 k UuidFromString((unsigned char *)GUIDString, &guid);" V" ?$ x g1 j- k) V' V
break;
; {& Z0 ~, G% { K! h/ f, n }
# c7 O: I. a9 V% D O* O6 K2 b# W% @( L3 x; Q5 J
hDevInfo = SetupDiGetClassDevs(&guid,
" ^ t3 X3 i3 ?% O NULL,
; s3 U) ~ L5 j NULL,6 v# f3 S* W3 }% z2 H2 o \9 L
DIGCF_PRESENT);
3 ~: M: E9 @1 k9 w if (INVALID_HANDLE_VALUE == hDevInfo)
6 k* c8 o/ }, R& b {! ?$ Z3 u0 U4 v: u9 v
FormatMSG(GetLastError(), &lpszMsg);& b. j; S$ o& G; O' K
throw lpszMsg;
* V) R1 P+ S% V }
3 _& ~/ ?2 f( X* d
: S9 V$ z6 U* `2 z3 d# ?3 L, X DWORD i;7 W* n, y& p! J% D; k7 J) n- z$ l
SP_DEVINFO_DATA DeviceInfoData;
8 ?5 L; R, S0 A2 } ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));& g$ c6 S# D, @! ?$ r
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
6 O1 p; i" r% E+ C
# a) O6 x/ X$ M( V5 R8 U/ s for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)5 _) a! r" R2 k0 p1 q( b B3 {
{
: G9 m- H$ J# z if (1 == nStatus)$ ?, E% M4 d8 ^6 l8 y" ~
{$ d1 M+ X A/ s; w) R
StateChange(DICS_ENABLE, i, hDevInfo);
" m+ x: C# V& z: i }
2 s. j" l# t! ~7 p/ ? else if (0 == nStatus)
& y3 A( C" v( e% S3 z0 j+ E {' P1 l" E2 D& @+ `# _
StateChange(DICS_DISABLE, i, hDevInfo);, ]2 Z0 U" h$ M% f& F: W# Y2 v
}
9 V" a/ i5 N i7 ~ }
3 z) b: ?) w. k4 p6 E" U
! j7 P( h3 s; D8 `! s // 释放 device information set
3 @; u/ G6 v: m return SetupDiDestroyDeviceInfoList(hDevInfo);
( y8 i/ z7 A3 V$ Q' |4 G4 ^}
; q* h% y# }: g9 ocatch (TCHAR * pszError)
: k4 @ ^6 w# i1 t{8 Y! D8 p( |5 E/ q9 d6 w8 {
::MessageBox(NULL,6 n7 K5 a: K2 z7 t
pszError,/ _& f: ^2 D" o( _' ]; }5 I+ B
_T("提示"),+ q* V9 z% f- ~* Z: n4 K) ~- [4 a
MB_OK);
) M5 e& c/ p% X0 g8 O if (NULL != lpszMsg)7 g3 c" m- P& q
{# B$ q) }1 N2 `! r# W) X
LocalFree((HLOCAL)lpszMsg);
' ^2 w' E, P6 u& K- T% } }
8 }7 ?+ G2 J4 X* }( g return FALSE;
* y l! h! q. e! }! k}2 o# g" k+ v+ W9 h% X3 o: L
return FALSE;
8 m: J; E1 g7 \}
$ I; s ?2 F6 B1 k" T" ^# ?1 H" x2 q0 F1 a4 @
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。6 K" w1 k% _3 M# {1 S7 j7 c
据我观察,在注册表的此项下下:* F# `1 F8 n3 y2 Z. C" S
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\' a5 [8 ^4 S$ v0 ]1 x: U$ s
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
. S, n3 [/ k1 ^1 u {36FC9E60-C465-11CF-8056-444553540000} z2 R \; Z3 j9 K- U8 Q
这个是CDROM的* i- O0 @8 K$ W! F
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
! }1 m& J9 r) ]* x- D5 [. O这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|