|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)" h+ k+ V: A# |5 b3 Z! @& Q6 Z' ]
- W) n4 ^" Z: |
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
1 F( K: u/ }! s% E% V; y: M# ~// 必要的头文件和要链接的LIB文件' n. X% M; F* x M) a3 K
#include <setupapi.h>
: y/ R6 ^0 I" J( u#include <shlwapi.h>; Z/ a! D( O( e& u0 \/ z
#pragma comment(lib, "setupapi.lib")
/ a$ t* C) T* z! X, @, ^0 b' u#pragma comment(lib, "shlwapi.lib"), J3 z! z8 V" M, o
' Z2 O" w$ Y3 f0 l6 S! y
// device information set(我把它译为设备信息集)
7 E* p1 ^" H7 X# T4 v$ E oHDEVINFO hDevInfo = NULL;/ `# h2 q0 L7 X. @7 \9 p* K9 ?
2 N9 F" _: E, ]7 q
// 出错信息- w9 D4 d& i2 h* u
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)2 f& c, R& [; K* S
{ 5 m+ r' r" i! }9 k* |
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
' v$ n/ U% A2 Y: y+ ?3 | | FORMAT_MESSAGE_ALLOCATE_BUFFER,* B" u( Z5 m. |3 d- ~8 e: `
NULL,; }/ R5 x3 i: ?7 b3 K4 |1 e
dwError,; Y4 Q8 r6 p0 h1 h, q/ M. w. d% ~
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
, u9 v1 f0 e! j4 ~ (LPTSTR)lpszMsg,
d; y% c6 n; Q 0,
; G* {( a8 f4 s' V" o2 H$ g* G NULL);# O" f$ L4 \) ~+ j
4 L3 w: Z0 J+ [, ~$ W4 Bif (!bOk)
* k- C& A9 T" G. s& w, s{0 k" j: K9 C5 z" J
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
! L3 P/ O* n$ n* \& J NULL,2 P( L0 Y- p2 v, w( e* E3 d0 t
DONT_RESOLVE_DLL_REFERENCES);* O. m* T- D. b: s0 D) {5 G9 d) g
if (NULL != hDll)
) u7 d W0 Q( U/ T, b( P0 Q {) {) i) Y; x$ ?
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
7 H- g8 d3 ?3 B+ h* r s) H FORMAT_MESSAGE_FROM_SYSTEM,- _7 T: ^3 X" W: V0 c
hDll,
+ k: M2 X! r7 C% q& l: x: P% m6 Y7 W o: e$ g dwError,& s2 K: F7 R. j! `0 ^
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
6 n1 J) P; i1 w4 \% D" @ h. Q (LPTSTR)lpszMsg,
6 }9 P+ m$ f8 l: L- y 0,
! o0 j& r6 K) B$ Q$ ? NULL);
( \1 |1 h- i' m J FreeLibrary(hDll);6 z& d( o. ^) F1 x8 V/ ?
}
* Q& J, b4 `2 O+ ?; Y}, B, ~6 L. O- N6 @$ k* ^% O! z
}5 F) w" v* C" k Z6 A) x0 w
' w( b6 o. K- }: ZBOOL ChangeStatus(DWORD NewStatus,
# K p( ^4 d7 d' Q X) [ DWORD SelectedItem, / P# _2 d1 _) l6 B0 P5 W
HDEVINFO hDevInfo)
* m" T& D$ C* S0 O( g{
. {$ R- P) f) ~3 _0 vLPTSTR lpszMsg = NULL;' @& y5 d) @% j9 P |6 m
HCURSOR hCursor = NULL;3 s* L7 ]* H9 s, g, b; i$ H( }
try
! u! L. ]* F! G& y$ c{
% Y" \2 i* u8 l3 T) |0 ~3 ^ SP_PROPCHANGE_PARAMS PropChangeParams =
& T$ s9 P) n! d3 ^/ l' q {sizeof(SP_CLASSINSTALL_HEADER)};
$ Q0 a- J9 d; @7 y SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
8 y, J' C! }% l2 L
. o. R$ W( t5 q2 O% G; @ hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
8 i3 U, B5 B Q3 A# }
1 m% j: I) x7 o) o" c0 V // Get a handle to the Selected Item.4 _4 ^& k- A& _& z7 g; l
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
. k9 n# z0 v X) i {
4 F! Z/ w& }* X c0 K8 N FormatMSG(GetLastError(), &lpszMsg);8 i- g% A* m7 L' i+ o& g f6 | w
throw lpszMsg;% J! g( ^$ j1 T% M: ~3 t/ U# D
}0 d" c: B" ]& x9 k, X4 ?
$ k* M- E) {" A& _4 C // Set the PropChangeParams structure.) O! C, m2 V/ N+ {# c
PropChangeParams.ClassInstallHeader.InstallFunction =
! Z% l4 v4 C% x" Z- g DIF_PROPERTYCHANGE;& l4 ?" H8 X+ R1 h- U* z1 d( R( u
PropChangeParams.Scope = DICS_FLAG_GLOBAL; I ^3 q$ s" A1 l' o5 {5 Y% q
PropChangeParams.StateChange = NewStatus;. {# J* |0 a- n* R9 J
7 v. m5 B o: z2 C u3 W2 e
if (!SetupDiSetClassInstallParams(hDevInfo,
8 F! c$ p6 J# `8 R &DeviceInfoData,
' C8 n \) M& V (SP_CLASSINSTALL_HEADER *)& ropChangeParams,2 \0 G+ }: P% V4 h2 U
sizeof(PropChangeParams)))$ y/ E% I) U2 }* r5 o+ I; s
{9 p5 N' v8 t2 Y! ^& Z
FormatMSG(GetLastError(), &lpszMsg);
! j3 T# v! j6 V& E, a4 I3 ~4 r, k throw lpszMsg;- y* g" V$ ?' e% J8 V* F. Z# h5 @
}: E& B# @$ `: ]
6 \& I$ k7 U! u* ^# e1 v // Call the ClassInstaller and perform the change.
x# q5 o+ t, U, t4 J if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,5 e9 s. v8 z% o' d! Q: v
hDevInfo,0 C8 }& \7 Q$ n# G4 }/ Q+ |
&DeviceInfoData))9 {1 X/ k5 B) G5 t. ]& Z8 d5 k" o
{
0 J6 m9 c) ~: Z% h* K FormatMSG(GetLastError(), &lpszMsg);
$ b! p! D( { M( b throw lpszMsg;6 G# E6 Y) g, U. n& O6 @
}
2 t- {1 h9 v5 j+ G2 E3 k
4 f4 Z' Z6 i0 L8 L, \+ g- C/ J SetCursor(hCursor);
+ ], m. d; ?3 u7 c2 V1 X: h" [1 e return TRUE;
+ q! O: r, {9 r+ U}
- N1 \" P2 s9 |* e$ y4 Acatch (TCHAR * pszError)
8 f5 x, |$ O9 f/ K! Z# O+ ^{
9 E0 ?! O5 o, I2 J2 ] SetCursor(hCursor);
9 f d: g7 Z8 R+ P" T, w" [ ::MessageBox(NULL,, l0 d2 K: r% s- v
pszError,' F8 K/ `+ |9 z. Z8 a6 i, d
_T("提示"),4 K$ R( j# X# h( B( {+ s
MB_OK);
2 F [2 Z& H% W1 q if (NULL != lpszMsg)4 ]6 h2 @" x5 t' n U+ [
{
8 @' {+ ]9 N, Y# y3 K" ^ LocalFree((HLOCAL)lpszMsg);
- P6 A: N) H3 }7 L ^ q } : K% c( j6 y% x' F6 A) |
return FALSE;* H" k' Y: ]- P0 g
}
1 l ~ I0 t. o0 X6 s}2 s& \ K& y8 q/ D2 k: Y, M
1 J2 j8 u) q9 x- ~# @# F// 这些设备的启用和禁用主要有此函数实现) ^$ [. f/ X5 P) M8 T6 ?. x
// 参数说明,nStatus 可取3个值,-1 :啥也不做
3 C! r+ J: ^: ]; C/ X% K1 M// 0 禁用设备,1启用设备。! P+ ] Z6 H( }+ u+ Q0 u
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用( }( \/ q9 }$ F$ g1 Q
// 也是可取3个值,0 代表软驱,1 代表光驱9 |2 |4 ~0 B, ?! g
// 2 代表USB
" a8 H/ c6 L. ^5 K& W// 譬如要对光驱实现禁用,可以这样调用此函数- _% M7 u! M# n* S+ V, }' g
// ControlDisk(0, 1);
; _2 E" o: l5 ^1 D9 bBOOL ControlDisk(int nStatus, int nIndex)& G1 ^* L! o4 m! m$ {
{9 I1 V9 \# m0 [' W! [# {% G
if (-1 == nStatus)/ J7 d! H9 f# ?) T& i7 X7 K, w3 [, [3 C
{
! H- Q/ d1 F+ W$ d4 ^, U' g return FALSE;. C/ T6 o, t/ o1 w
} 8 N' o" E' [( b7 b6 c" p
/ H. `$ X Z' F
LPTSTR lpszMsg = NULL;
( q' K. U2 j! \8 V' K8 Ftry, ^9 [' S% I! ^. ^& c' f1 j
{* q9 t6 ?8 Q+ @
TCHAR * GUIDString = NULL;# _1 r: q6 }, P r6 j
GUID guid;4 ?9 N7 v% p6 x- F' e& z+ ?# A
ZeroMemory(&guid, sizeof(GUID));, n4 [# W+ H) j, k* c: X3 | e5 n% v
switch(nIndex)
& ?" ]( q0 C6 ~* D- A3 I {
- c0 M. b6 g1 z& U) R7 ] case 0: // 0 代表软驱
: ~4 A) H' [+ s2 V! h* ` GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");7 h0 {. o+ J* L
UuidFromString((unsigned char *)GUIDString, &guid);
7 W0 e) M* g N1 t break;
2 E8 g( x* R7 u( Q case 1: // 1 代表光驱
- ?7 @1 t2 y$ R- Q- w8 T; L$ g GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
0 S- g3 \3 U2 p; ~2 W; h UuidFromString((unsigned char *)GUIDString, &guid);
# `) a, w9 s. t& S break;
$ s3 m& P s: ~$ h, M- {2 W case 2: // 2 代表USB9 A0 j9 w; p3 s4 ~
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
9 Q. c4 Z7 [/ Q7 E$ K UuidFromString((unsigned char *)GUIDString, &guid);! T6 ]4 g! l% A6 |+ |5 Y8 r
break;
0 S B& s0 H, Y# T+ N* n }
9 M \5 l+ x' b; @: v' S3 w# A& y9 R) Q) g7 l
hDevInfo = SetupDiGetClassDevs(&guid,6 h }: N6 d e1 ]
NULL,/ Y$ q6 v- h3 B% i! w4 _$ b* \
NULL,; A- o* d# K0 N4 N, t7 S) c8 `
DIGCF_PRESENT);
2 ]9 h- W' v- U1 s: C if (INVALID_HANDLE_VALUE == hDevInfo)1 I' |3 Q1 `* G8 O
{- O" O; J) ?# w- A$ a2 a5 {
FormatMSG(GetLastError(), &lpszMsg);; J6 x, j( l V& O% h. r9 C
throw lpszMsg;$ p8 J9 |+ Q. w. T% u: O% W
}
; ]2 h7 E4 |5 E% a- R0 l$ g1 y1 w
* ~* y' g( h5 x% Y DWORD i;3 Z/ y2 b* ~& y( }; f! X- ^
SP_DEVINFO_DATA DeviceInfoData;$ z9 C1 M8 w" S: N
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));* q; q4 \! ?: u* Z# N
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);1 u \! d: m0 }) S+ r6 G! n" d1 ?
, Z3 o$ X! _5 z* J- i4 w) N6 ^
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)& u% f0 A3 {1 n; I1 {
{
: Z- z" m9 r- w, F if (1 == nStatus)* q: w% [- C# \. m! p( F
{+ J& [' t5 V4 H8 T. `% X2 \# i% B
StateChange(DICS_ENABLE, i, hDevInfo);, M- A4 S z( t/ _
}
# @' ^. `+ Y. ]( S4 z" a+ |0 h9 Q3 ^ else if (0 == nStatus)
( |" L9 _4 S3 Z5 c* n) ? {8 k9 {0 X$ n0 H3 J) Q8 n% f
StateChange(DICS_DISABLE, i, hDevInfo);1 x8 f: T8 A) E1 g, c
} 8 X7 c" ?- l7 J# ~7 n
}& o9 t$ t: J) N: s- R
$ F6 C5 X- k3 P' J: |5 C: G1 ]
// 释放 device information set5 X: V$ X1 [- |! O# V% W
return SetupDiDestroyDeviceInfoList(hDevInfo);8 o- U) j* I3 q$ K5 H
}3 z5 z1 d9 S S
catch (TCHAR * pszError)- E9 y2 l) A7 j/ a7 m% i
{
- n5 X6 ?2 i+ ?- e ::MessageBox(NULL,
) Y+ A1 S- N( T2 I9 F4 e8 v; E pszError," Z1 I2 s$ N$ h8 K( o6 l
_T("提示")," q3 U) e8 W" g' i7 r
MB_OK);0 P' \( U& T5 [% U9 D
if (NULL != lpszMsg)
/ B( _; ^ A8 f4 R2 Y {! H9 \8 U8 [% J* R+ u) [
LocalFree((HLOCAL)lpszMsg);
7 w+ t4 C" I( K3 u3 `% } } % H: Y% y# }, @ P! b
return FALSE;
5 N; n D" K: z2 l}! p L& D8 Q7 o2 e6 [4 O6 Z
return FALSE; h) v6 t- m4 p# w( T
}
) \3 {2 p/ K" w' p5 L2 A
2 U7 \$ p, [& s0 d, C 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
4 s {8 J+ B. h4 v 据我观察,在注册表的此项下下:
, D7 w- w. ?1 [7 h3 }7 [0 I HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\& |4 Z! v4 q, G. m; ]2 s
有很多GUID,每个GUID代表一个设备,譬如这个是USB的: g, o% L6 ~. C2 k* _) X
{36FC9E60-C465-11CF-8056-444553540000}8 y/ a* ? B0 M/ z2 W3 \8 s
这个是CDROM的" e2 @* j6 R2 F0 X
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
1 w' C/ c' D0 q3 |这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|