|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)1 t& X: E* p& Y8 B
3 j: J2 T, N" h) O1 W1 F% Z" x6 W这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:6 l1 M1 H/ F) Y0 |
// 必要的头文件和要链接的LIB文件: k5 k& H& _; U4 `* ]: U8 c: I
#include <setupapi.h>0 n% P) j0 h; {( w
#include <shlwapi.h>
7 w; w/ B% }: i% h* k4 a" Y& I#pragma comment(lib, "setupapi.lib")
" H+ e' N/ a) R2 ~5 k#pragma comment(lib, "shlwapi.lib")* I" P1 Z) T5 a: l( g" k7 n
+ l; y" @; T1 m( D l5 y
// device information set(我把它译为设备信息集); a r7 Y8 w# U5 I' R
HDEVINFO hDevInfo = NULL;
+ n7 D' O8 B8 a8 @
9 S2 o Q3 v: |' r: c& ^// 出错信息
8 }. f; u$ K' d4 o( V& nvoid FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
( }2 l0 r* w9 o# S{ : O6 F$ L, t4 w# H
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + l3 C+ w0 H! _' D
| FORMAT_MESSAGE_ALLOCATE_BUFFER,9 }& e. l- ~( Q/ s. e, u6 z
NULL,5 @3 P: a! K# X) k/ T& u9 E# [
dwError,
) E; o) C& O/ t' X9 h/ N MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),2 r5 X% }6 M8 v
(LPTSTR)lpszMsg,
# D' \: p! |2 v' G7 ~# R- v 0,
6 j+ k, a5 y/ Y3 n9 [4 o! Y NULL);! Q3 B& H) o6 |' c
' b& k) F7 [; L$ ?2 j Z0 @
if (!bOk)! s. h; q" h; w8 E( i" t
{
, p ]+ B- u. v0 v( h HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
! b4 ]; B5 q i" B: P' c- G NULL,
2 C% @! E( B5 H: z0 t* B+ W DONT_RESOLVE_DLL_REFERENCES);& y3 J2 g) x/ r8 o- c) {6 m" B% U
if (NULL != hDll)1 O+ w2 v/ U5 B, F% [$ y
{$ h0 O# w# ]) n7 a9 V5 f5 k
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | ) O( l/ G2 q& i, O* b
FORMAT_MESSAGE_FROM_SYSTEM,
4 I# S2 \2 A f1 T1 S0 E/ j hDll,
' _0 I i3 {4 ~- u, _ dwError,
0 _! i: u" e& v) |5 i3 G* E, R0 ?( ]/ v MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),) ?+ S* }( G, ~( p- x
(LPTSTR)lpszMsg,
9 [2 H$ U" x( h6 Y5 V* ? 0,: K, U- ] Q$ I" L4 z$ O
NULL);
# T; [) P2 E* j2 [+ ~ FreeLibrary(hDll);
& t4 s5 c5 Y1 L2 q: f }
9 _8 e2 F* r F! s" K2 u}/ H- F" G1 _9 |2 ]
}
3 t; d" @- X7 A ^ N1 S4 X; l7 P& ]" x8 J: l5 ^) [
BOOL ChangeStatus(DWORD NewStatus,
% @3 ~( p3 A5 l( K) j, p DWORD SelectedItem, 1 Y. f* q0 Y/ u4 p7 N
HDEVINFO hDevInfo)' X% n! C' z6 e. r& |* f/ [! A
{
; E, @% e4 y* D o! PLPTSTR lpszMsg = NULL;3 p \' X$ q0 d; }8 T
HCURSOR hCursor = NULL;2 z/ \2 M( t9 b1 x
try
- H' I0 w, b' J{7 D" z; D# Q. A7 t
SP_PROPCHANGE_PARAMS PropChangeParams = $ h* u# j6 o& W
{sizeof(SP_CLASSINSTALL_HEADER)};5 S& @. z" |- F2 i6 _
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
2 c% ]+ o+ l% D4 }9 C8 Q! B: Q8 K
2 O; {$ d2 i% ]* u3 P hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
0 m' C! C4 l5 j
' l/ b, B4 u: [( y; }; @ // Get a handle to the Selected Item.
2 p/ m( e! S$ W% _' y if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))/ c2 I7 _- w3 Q* ` q
{- v* j) Q6 H& s. b, }& n6 C0 v/ ^0 }
FormatMSG(GetLastError(), &lpszMsg);( c0 v: {! n) K N# @% h: n7 x; c9 q
throw lpszMsg;3 k# f% L3 t1 O: F$ d2 {
}3 i7 A4 A- W8 [8 N6 P* i
4 J% Z" V v" T6 I0 l E' c. @5 Q' O) | // Set the PropChangeParams structure.0 n# a6 M5 I. h0 L+ {
PropChangeParams.ClassInstallHeader.InstallFunction = 7 }; v3 S2 Z9 B1 e- u
DIF_PROPERTYCHANGE;& t S, j7 S1 |( N3 H( X
PropChangeParams.Scope = DICS_FLAG_GLOBAL;1 s7 r! n' F# h. [2 z0 B, H
PropChangeParams.StateChange = NewStatus;! ^) P2 T `2 G# L
$ V* g7 `# x+ A9 ]3 d9 B if (!SetupDiSetClassInstallParams(hDevInfo,% U6 N; B1 z* }! z6 r" R
&DeviceInfoData,) L4 N0 ?1 b- b/ N
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,1 v6 W H `/ c
sizeof(PropChangeParams)))
/ O9 j7 }6 Q: q+ H' p {* E8 ~7 I# z# ?. {" m
FormatMSG(GetLastError(), &lpszMsg);
6 U- t ? L1 g& N; V throw lpszMsg;
4 N$ p5 R( x, o) ?; c% Q6 O }; e2 l% y7 I, E4 u
7 d7 I6 @. f- ?/ L# c! E B8 d: R
// Call the ClassInstaller and perform the change.
; |% t+ P( a4 R) Q if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,! P7 p/ @( v: Q2 w2 g! u( A3 l( s
hDevInfo,
+ G" w m: w- R9 O &DeviceInfoData)): [2 p3 r/ n! D7 A% h
{
8 n2 w" l& G- R c# N FormatMSG(GetLastError(), &lpszMsg);: K* Q3 `* V; G: `; e& s# K6 l
throw lpszMsg;; k o2 Y) N2 I% K
}
9 H2 [ r! O* X: [9 R) W
8 a" d/ ~- F: N7 ~9 ^ SetCursor(hCursor); ! P9 [% G: A1 H: ^( X; O$ [8 P
return TRUE;; e, f# F4 P# a% H3 R; k
}
& `. a4 ]9 c/ @2 f1 }! Q+ u9 {" E& \catch (TCHAR * pszError)
. A. [1 ^. \ N' v( ]{- c4 K' c* c7 X
SetCursor(hCursor);
# Q% `# d. f6 f ::MessageBox(NULL,
* q3 H% s. Z' r- Q pszError,& [" |5 Q- V: I5 E& C- a* N- T! f
_T("提示"),; J3 s) y# I) d9 m
MB_OK);
. F! V; N2 ?+ `! r6 F) z if (NULL != lpszMsg)% r6 H# x9 R. n; e
{( i# n# }$ a! N+ b2 s
LocalFree((HLOCAL)lpszMsg);
2 Z: O* X# D1 u" n# \ }
! ^$ Z" _- }) n! ^, M return FALSE;% m% F- ~$ K& Y) W/ q1 t
} + X% e% u6 o }: f6 \ A& g
}4 r; z. l9 k$ y* Z3 Y, {2 b
# v; N" ]3 p/ Z9 c4 E/ g// 这些设备的启用和禁用主要有此函数实现 c( A# `8 m$ d" b6 l2 s- L7 j: d
// 参数说明,nStatus 可取3个值,-1 :啥也不做2 V# K# q# F% v0 j4 \3 w! [* m4 F
// 0 禁用设备,1启用设备。
: B" N5 o) P1 g- ?2 q// nIndex用于控制是对光驱,软驱还是对USB启用或禁用( J Y. c" R- f& s' |
// 也是可取3个值,0 代表软驱,1 代表光驱
4 F; \ s$ z J0 G- \// 2 代表USB
- M+ c0 t+ ]! f4 l// 譬如要对光驱实现禁用,可以这样调用此函数- [; C. y+ y) s4 f7 C
// ControlDisk(0, 1);& g& e3 Q7 m c$ P) \
BOOL ControlDisk(int nStatus, int nIndex)
3 j) {& M( ~$ p1 S( d& @{: g" a9 O2 |4 K' ~+ g, C& N# o
if (-1 == nStatus)
* Q8 ^8 M6 }* K, `, a( O{8 T) O# k2 N; x# h% W3 R. A/ X' ^
return FALSE;
2 t/ @& ]( r; Y. ?2 d}
8 ~' C% f) F( E' P" I" U% D& ^
) ]% [& y8 i- O' g2 u GLPTSTR lpszMsg = NULL;
7 G) R7 a' S- T" s$ s) ]try
6 Y" K: ~, o% u8 I* O- v/ B2 ~6 r{8 j" T9 {! j9 t/ b! b. I) e0 K
TCHAR * GUIDString = NULL;8 _# K- n% E" q0 D4 I) H
GUID guid;7 X* o' X6 Q3 v* v7 q% H \
ZeroMemory(&guid, sizeof(GUID));
# f/ n% z$ r1 Q' p switch(nIndex)+ d8 \) S& |3 [9 `- P4 o
{
6 ?) L2 Z a" q4 G case 0: // 0 代表软驱
& M/ b; L" y4 H1 h3 w3 @ GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");8 p+ s7 M" Q, g9 S2 @. a
UuidFromString((unsigned char *)GUIDString, &guid);
- D9 ]5 W0 i1 o, t% r6 I break; ! D3 I- ~% k6 W# V: z) N3 C
case 1: // 1 代表光驱
$ P! l, A- |- K! |1 w7 {2 c' d7 r' [6 r GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
9 D2 x) e. D0 k5 w, @ UuidFromString((unsigned char *)GUIDString, &guid);
9 S# V( Q* ?, K0 x9 c+ C break;' S6 X! s2 o* z9 W
case 2: // 2 代表USB
* H v( ]4 z6 w+ q v- l0 R# O+ S+ O GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");* G- w, }: @0 i5 y0 o2 T* |
UuidFromString((unsigned char *)GUIDString, &guid);
( C! r. p" W. @% D0 X/ w( i break;& h# r, u4 Y0 M+ v( }8 [! z1 L
}% X8 E+ d' s. }; Y
7 R8 ^# r3 s: n7 v4 \- Y/ I, @( T) U; n
hDevInfo = SetupDiGetClassDevs(&guid,
/ y0 K4 M6 F( {6 E NULL,: K1 M; q9 V# Z5 z# ]% i
NULL," J2 u4 ]6 M; d9 W2 ]* `( Y
DIGCF_PRESENT);
0 [ q# W: P# L! T' j if (INVALID_HANDLE_VALUE == hDevInfo)# d+ U/ \% @) ?( q) A
{, y ]4 f) w4 m
FormatMSG(GetLastError(), &lpszMsg);
I! V2 f5 G' `& W. } throw lpszMsg;
, [2 V4 n4 z! j+ X; ^% }: G; v }: v& ~) v b9 t& V8 X
$ ]- E1 R! D: P( O _; I DWORD i;, ]; w6 g1 d8 v# h. [3 r
SP_DEVINFO_DATA DeviceInfoData;6 M+ L; O3 j& O9 ^& {( a
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
: ^! e2 K ^( f0 g, P DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);/ \* B' y' Z* z! ^$ }
[( O0 V9 T8 y/ j1 z K
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
* A3 e8 @$ `) Y3 B9 k6 b {8 i% G/ ]$ C9 M0 h# j( U( b* q F
if (1 == nStatus)
* z- @ P9 r* I- d4 C {
4 y- i: Q5 ~9 T; i7 _4 F) y StateChange(DICS_ENABLE, i, hDevInfo);
8 B: z2 f D0 Z3 ?. ] }
4 `1 j K& o% A else if (0 == nStatus)/ ?# d( j$ @$ [4 s3 N2 }+ {" r
{3 H9 t$ p' T; n @2 \2 O
StateChange(DICS_DISABLE, i, hDevInfo);
+ U; t. z0 K& X2 u }
; E$ j6 C9 w! z+ E8 A; P }
0 F/ u- y/ w4 d: G% W+ Q3 m* o% K( P" W4 s# F
// 释放 device information set
8 } Y# P- b* g5 e- t, u5 x return SetupDiDestroyDeviceInfoList(hDevInfo); M. Y+ a/ y4 S% N" f! i0 n. V3 q
}- S0 n1 }+ @( J1 g
catch (TCHAR * pszError)
/ @6 d( [5 K: c{( D: D) a- V5 ^/ A% A
::MessageBox(NULL,7 O! b2 I1 q- D( Q' Y& ~
pszError,6 l6 S7 M$ V. }4 a
_T("提示")," ]! O1 `/ o9 I+ I G/ W# }
MB_OK);
, Y; F8 a9 c. Y$ H- `/ | if (NULL != lpszMsg)+ L7 m: w n3 k% ~' ?
{
1 e% w" m+ M) U LocalFree((HLOCAL)lpszMsg);1 A# F+ s% f9 A" |* ]
}
" \( ?9 A' H+ u+ [# ?0 f return FALSE;9 _+ W2 e; ~& I/ k* t
}
* `* P, [+ i! D4 A3 U. Treturn FALSE;( r7 P7 d* b% ^0 P' P6 A
}$ Q# i. l0 {1 y) t3 Y
+ p0 d! K% x) @- A 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。0 h, _$ b0 `6 E0 j/ K) ^
据我观察,在注册表的此项下下:
, Y. e* @$ X$ T1 c' u HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
0 j, C9 |; y* a% W; S. q, k 有很多GUID,每个GUID代表一个设备,譬如这个是USB的
7 e7 c! v7 ]& q0 G9 g {36FC9E60-C465-11CF-8056-444553540000}" X+ U: j+ l. V$ M
这个是CDROM的
% c7 i6 l( H8 i& l {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。0 Y/ Q) T$ w$ d! {- s8 R' _
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|