|
(dlutyuanhongl发表于2005-3-15 23:14:04)
' _7 L. B# g9 F$ P
( B+ y. w- t4 t. k; c1 Z这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
; k! |3 U" Y$ w [7 [7 @// 必要的头文件和要链接的LIB文件
: L& ]9 }4 F! V6 L- @#include <setupapi.h>
5 b- w. P5 U* m8 P3 t6 [# B" L# ?#include <shlwapi.h>
, g. c% b' N+ b% p. ^#pragma comment(lib, "setupapi.lib")" @5 b3 y2 k' g: h; ?
#pragma comment(lib, "shlwapi.lib")
+ ^) B6 a1 R4 `! _4 g
. e8 i. u) E4 Q# P; Q7 F// device information set(我把它译为设备信息集)
/ {& e# D, U* r' xHDEVINFO hDevInfo = NULL;
' L) {8 m! ^( X, g
- F9 Y w1 h( ]( u) {! H1 Y. v// 出错信息) W+ E( V/ |! G5 B5 U" H
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)) @' c4 g$ O' s
{
) N/ F( W( q4 D L BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
$ m0 W! U! e$ N) z# H | FORMAT_MESSAGE_ALLOCATE_BUFFER,
9 C4 |7 X, R$ ?% C NULL,, d, T8 R; G/ r' p& f1 q: H
dwError,' r) o+ J# r8 D/ x, F: }* T
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
4 H4 C+ D- h2 Y (LPTSTR)lpszMsg,; C$ N/ S* `* h/ i; g( w
0,
4 Z' Q' W- s- U, f NULL);
3 M8 A0 a$ M' g9 l' D, ~ `1 @6 b+ @, R2 H, k9 e: @
if (!bOk)
) s- }2 {7 M) `0 @6 ?3 `4 C* [{" A+ ]: o( }3 }
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),8 c" k) \! G1 S
NULL,
' s ~' D. I* L; |$ { DONT_RESOLVE_DLL_REFERENCES);2 y1 {' X( ?! p1 S
if (NULL != hDll)4 @. Y: o' r0 S2 v. Y2 p
{
& r5 ?0 d6 K8 ?% O* _2 E FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | " _: H; q0 y: ]7 m
FORMAT_MESSAGE_FROM_SYSTEM,7 D8 X6 d4 ?. {# I/ z$ x
hDll,; m0 g+ ^. i( Y# X* J
dwError,2 F+ l2 s) q9 [6 ]- u2 T
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),+ q4 y! \8 y2 [2 n$ F
(LPTSTR)lpszMsg,3 ^2 Z5 U+ R, i; ?" w
0,
$ p% v/ a; \7 U q NULL);
! v& Y" A9 ^6 N. ]9 S; T' W2 U FreeLibrary(hDll);
& ^/ N' B0 c3 |! i5 Z/ E' H }
5 v( s! o& @$ Q# B% x3 y- w}2 M) f( D, e- ^5 O
}9 n& ~' r" [+ x- j B9 M, `7 I# ~9 ?
( D9 w% |$ r# ?
BOOL ChangeStatus(DWORD NewStatus,
5 T6 [1 ?2 i" l1 w/ l DWORD SelectedItem, ) u9 D% y, w" H. |4 u1 ^
HDEVINFO hDevInfo)
0 U U; ?& Z3 {' o{5 E; s* g& l# g1 w. @9 m
LPTSTR lpszMsg = NULL;
- ~9 @* h3 K$ w) `HCURSOR hCursor = NULL;: L- w, t) z- b+ ]* s% w
try, S& x! ^! j9 Q/ g! k
{
- L9 W4 `6 D- ]2 q2 b2 b% |3 Y SP_PROPCHANGE_PARAMS PropChangeParams =
5 C1 o0 D1 _8 d9 V5 T* o9 v4 } {sizeof(SP_CLASSINSTALL_HEADER)};
8 `5 \1 O+ n2 V; ^8 K- t SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; ' T, @. r8 u! C" _
4 ~! `% V* R/ ^( J: M
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
. D2 ]: k8 Y/ a9 i5 Z2 G# B/ \( S6 q# s; O
// Get a handle to the Selected Item.
/ s7 L0 p* A" @+ F+ F if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
: k% U, ]: G$ Z9 o, [3 G- a8 S {
) J; q1 C) }1 _7 \7 ? FormatMSG(GetLastError(), &lpszMsg);9 ]& E; w, ]. H* B$ K
throw lpszMsg;1 T. [. D4 l- m5 ~0 K8 s9 O
} e) U5 m3 o5 t: I) ?1 w- P$ u7 E/ D
/ j% j1 s# C& j$ v // Set the PropChangeParams structure.
0 I+ h4 V5 l% q, q, m. X PropChangeParams.ClassInstallHeader.InstallFunction =
' d, [- j% Z0 }! @ DIF_PROPERTYCHANGE;$ Z) @0 o m8 D' ~8 `
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
2 U' e5 Z! |6 }2 a PropChangeParams.StateChange = NewStatus;. `2 e$ F( B" h/ \4 Y& o4 M! L
- E8 J: p* \" v# M% b8 F if (!SetupDiSetClassInstallParams(hDevInfo,9 f3 L+ I# K m$ R
&DeviceInfoData,; E& w5 Q0 a$ a( P u7 O
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
- m3 H5 W# V+ C6 K- H( d sizeof(PropChangeParams)))$ [; ^5 e4 b7 ]* N
{" M A: b: {. n( Z
FormatMSG(GetLastError(), &lpszMsg);! e, w& \. [* B0 y0 B1 l
throw lpszMsg;
( P7 i6 ~' }5 S$ q6 [ }
, R) z$ f# A' N9 b0 m5 e- P: q6 [5 [) l8 r5 s
// Call the ClassInstaller and perform the change.
" |# p/ q; F$ ?% q, O/ f4 p: M if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
3 G% K' F$ H( O/ X0 ^) F! E5 l$ w hDevInfo,! ^# m6 G1 @. H6 l! l
&DeviceInfoData)); L& n8 B7 o' K2 R r! b7 f" n; c
{; g' s7 b) \" t& S- Q N4 W
FormatMSG(GetLastError(), &lpszMsg);8 Q8 @0 s* D% N6 F
throw lpszMsg;
( h' i: d9 h/ _7 v. L1 |& S. K; i m }6 z" i( ^$ @) N$ w* p# e5 Y
3 J8 f8 b4 T) [/ |
SetCursor(hCursor);
5 j( M0 ~. u& S k4 E, _) W. q return TRUE; N/ T; J3 z8 L3 Y# T V+ ?! e
}& c$ d( g3 f) o1 k1 p# U* p7 ^5 H
catch (TCHAR * pszError)
) J1 Z" x. n( O, ], Y! c4 U# Z) V. J{; b3 H7 r: Z2 t% q7 ]1 X
SetCursor(hCursor);
2 d/ G, ^% G1 ?) M, ?) ^+ v4 { ::MessageBox(NULL,
. q2 u. \9 s4 P3 o- C. p3 | pszError,
( b4 G0 g& ?6 P* P- Q _T("提示"),
/ ^9 y: P, Q8 ^! I MB_OK);, f- ~4 ?. g$ c, X/ I, N1 }
if (NULL != lpszMsg)5 v0 t8 J. j" C
{
; H, R/ ~3 J, _7 W; t LocalFree((HLOCAL)lpszMsg);* A6 Q( I& l9 |8 c
} 9 Q4 O- l' Z( K8 a; P
return FALSE;
$ b) i0 U* i* J! [9 @, G2 S: U} ( x* b- i# @( j" L
}
: R2 d* |' _4 g
1 o4 ]* ^. U {// 这些设备的启用和禁用主要有此函数实现
* P) ?$ U* ~, ^" V// 参数说明,nStatus 可取3个值,-1 :啥也不做# ?9 }: U8 ?1 v& c5 [. J, R- z
// 0 禁用设备,1启用设备。) j6 c( y) T% ^" M
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用
/ }2 B- U5 M/ x' L- @+ Z+ N// 也是可取3个值,0 代表软驱,1 代表光驱2 {1 D! B- h' _# K2 Y
// 2 代表USB
1 R0 s9 K1 C- {% D// 譬如要对光驱实现禁用,可以这样调用此函数
. _! j9 ^2 e+ X( o// ControlDisk(0, 1);
" o ]1 g. d9 a1 D: pBOOL ControlDisk(int nStatus, int nIndex)8 f \- v+ i# z, _
{4 E* [" A/ N2 M; N c- h0 P# I
if (-1 == nStatus)
8 Z, k. q( `6 h- D{* @$ s9 K# Y7 o) a6 p
return FALSE;; h( e Y! z6 d% u' V9 B' f8 `
}
1 k! a1 Y& q9 I9 g+ V; ?6 [! ~1 e2 H. D' w) @1 d( ^% h2 p
LPTSTR lpszMsg = NULL;7 _$ y% T! t5 E1 m* y1 X
try1 \# }$ U7 n5 W8 d0 R$ K- T
{6 X- z6 |! V: j
TCHAR * GUIDString = NULL;! k M* f% T( \$ Q. b0 K. w
GUID guid;
8 t2 O( Y4 Z) x4 ]9 `" k |8 p ZeroMemory(&guid, sizeof(GUID));: t D! h' e" k/ ^- j
switch(nIndex)7 ~- O" E" c7 S+ f$ s" ]' ^
{3 P! s4 L" e$ [% [
case 0: // 0 代表软驱
; N& o" |# i- M8 y8 y- g GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");" T9 E$ {) f% f0 e
UuidFromString((unsigned char *)GUIDString, &guid);
, S ~- B0 }! s break; 7 q' g. i% P2 v0 M
case 1: // 1 代表光驱 , m( B J- Z3 k
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");& d- i& W& X0 o$ J' v
UuidFromString((unsigned char *)GUIDString, &guid);% p2 x7 G3 _4 ^! e8 n7 \
break;
( b, |5 f" I3 S# f6 V1 f2 M case 2: // 2 代表USB; `- a4 W5 e* `! U$ @
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");5 V6 w( I. L' | w
UuidFromString((unsigned char *)GUIDString, &guid);# ]2 V, K0 l# v) V! B
break;
: n- T* R( ^+ }0 B, W# R }
$ x- Q0 q$ L( C6 D
. }0 x* t" R$ t; C hDevInfo = SetupDiGetClassDevs(&guid,
! ]& i8 o, X2 X: O1 g6 s NULL,2 _9 ~0 k8 L4 }# m
NULL,
* Q" I2 {' `8 @. f- A$ u DIGCF_PRESENT);
: H1 r+ _% V8 H8 O! E if (INVALID_HANDLE_VALUE == hDevInfo)9 W* d9 S" H- C
{
6 d+ ?7 p8 R1 R3 K3 n FormatMSG(GetLastError(), &lpszMsg);
/ v( [2 u4 k+ }+ F0 v7 g) f throw lpszMsg;
, \4 }- [. o( D4 u: a) A! I }
0 B6 L2 X5 y" f2 z H7 C
5 N1 r8 K8 m4 p& J DWORD i;0 J' A) \, ~* L3 a/ z- b
SP_DEVINFO_DATA DeviceInfoData;
" D- c, T$ M3 i( d# H! G5 O ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));- c0 D0 ~ t9 i! D# R' p5 F
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); e2 p* Q* Z- t5 }* a+ C
* {: T) g9 `! w- \ for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
; b: m# I& e, y& O; O {
- u/ [4 I! t! }2 o/ ?( ~ if (1 == nStatus) g- K2 p) V& v
{% R+ F0 J r* r# \, \
StateChange(DICS_ENABLE, i, hDevInfo);
) y2 G" |6 o; M- {+ d; V: H }
% _2 C& w5 T1 q else if (0 == nStatus)
0 k! w6 w `/ J. [8 R5 ? {
' o3 d9 `2 N0 w8 Y$ n7 @ StateChange(DICS_DISABLE, i, hDevInfo);
. X! `! U3 F/ ~% ` |, t& J+ l } * P ^7 L# [- N+ Y* y' k6 H! o8 K
}4 ]# E) }% \! J& J, K) E- s. [
2 k9 f+ c+ D7 x; m8 x5 a! M$ \3 V
// 释放 device information set
c6 i8 K( E# b/ `0 |. {" j9 Z return SetupDiDestroyDeviceInfoList(hDevInfo);
/ i2 e b! O- |: U1 R1 @}
# P$ |3 {) r# b3 j8 Mcatch (TCHAR * pszError)
, t7 D" m9 l0 v+ f8 a; o% ~ m{
9 R% y! b; T* M5 C' Y0 G ::MessageBox(NULL,
- [4 j9 }: N7 W9 A- B- _ pszError,
2 m* X1 \/ p! h0 g: w _T("提示"), S1 j" h5 U, s- c! K1 I
MB_OK);
: ]: f* f# g$ [) j# [* ^ if (NULL != lpszMsg)) U* f) \1 \) c
{5 I- d# g8 e j$ }0 w9 ~
LocalFree((HLOCAL)lpszMsg);
+ m8 K1 G5 I4 {+ G } : B5 a5 y8 z1 b( A0 |: s4 x
return FALSE;% x9 V1 L) y& ]
}
: e' H6 V L0 ~: Z: Ereturn FALSE;- X& L+ j6 b5 }5 T6 c
}: Q& ]/ z$ E0 R" H' ]) S1 J
# ?& t1 P- W5 V# ]5 n8 a 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
9 p+ Y; C5 m: E: E7 {# X: U8 _ 据我观察,在注册表的此项下下:
" D2 K1 w8 U& |' O4 G HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\0 q/ D' {3 I# f+ d _
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
' u9 U8 `8 ]6 `; B. M/ | {36FC9E60-C465-11CF-8056-444553540000}
6 X. z; i1 P: X 这个是CDROM的
& l4 L' [: U1 ^& y; b {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
8 l1 x" D+ t/ `# J2 A6 t( J2 k' Q8 E这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|