|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)5 q/ a: N" Q5 m% Z p) x
8 ^& A2 j' g8 c# N6 f |这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:* P& `: w) d9 L% F7 }& t. U
// 必要的头文件和要链接的LIB文件
0 c5 t! C+ `; C0 K* `#include <setupapi.h>& r4 N: p, a. @9 D) p( q
#include <shlwapi.h>
! l2 \, a- ~* P) @$ f/ d# H2 z#pragma comment(lib, "setupapi.lib")
. g% U0 J6 Z9 }( ~#pragma comment(lib, "shlwapi.lib")( X" ~4 k" |! b6 f( t* Y, x( b
" K" z$ B$ `. u// device information set(我把它译为设备信息集)& _- Y4 K. c4 e
HDEVINFO hDevInfo = NULL;
) J" n; r- c% X/ F9 m% u) z* }/ u/ F6 B
// 出错信息3 Q1 w1 l' s- u, F$ A
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
" z" D: }. T x4 p6 y{
+ ~) q) W4 t3 ?8 I3 i BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM & r# Q6 [* m3 f& Q& s. B
| FORMAT_MESSAGE_ALLOCATE_BUFFER,/ L, ?- Z) S( k( E/ H- {1 T
NULL,! g" J3 \! c" L% J
dwError,+ c" }, l3 [! S! S+ {+ E+ r5 I4 c" }
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),7 P2 ?# D& R# X( S7 |
(LPTSTR)lpszMsg,
1 k' Y4 N' o0 c 0,
( v. i. P, ]* E& G* ]2 ^5 Q6 f/ _- u; R NULL);$ g- O, j) A( {! i7 A
5 \) K+ o9 f: | f1 Yif (!bOk)+ C; |6 B& S& D5 q2 T/ K; |0 o( M) k
{, d( s9 h" g- m2 X! a
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),
3 [6 j- y& ~/ L. k' A NULL,
+ V0 ]3 o' N' S) o DONT_RESOLVE_DLL_REFERENCES);
: }/ I- |: p9 E; F if (NULL != hDll)1 W9 ]7 Z$ S3 H1 `
{
9 Y( t0 [) p/ j/ ?+ o4 e FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
3 A6 I$ l5 `1 V! ]! [ FORMAT_MESSAGE_FROM_SYSTEM,
7 c1 l' Z3 e2 A5 ~" \/ ^" B hDll,
( f3 K4 b% ^9 i( Y; n, F0 y! n dwError," {- |8 | T: z4 ~2 z
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),( w& B5 y; R1 O6 U1 V
(LPTSTR)lpszMsg,3 Y1 X( x- u7 `2 n
0,
5 e3 u# K$ E% ^; S" n# k L C NULL);) i" p( Y3 C- h( A- C
FreeLibrary(hDll);" m' G: ^) `( [2 E; {# x4 |
}, @2 O* f5 K& ^6 _" a5 X/ Q- J
}9 ~& v& {+ E& c. \- _( t
}
V v1 ?! r9 X. \$ P
- w. X) X( G) L' {BOOL ChangeStatus(DWORD NewStatus, : G. J: G# ~4 V$ C) P ]3 v5 {
DWORD SelectedItem, ! y( v& S& a3 E: m a3 `2 w
HDEVINFO hDevInfo)
9 P% J P" R0 {0 i: p! Z) X{
" {7 u5 b- v2 V/ W5 N( kLPTSTR lpszMsg = NULL;! t! a- Q% R$ }/ O0 H) }
HCURSOR hCursor = NULL;
& C& ?2 V; J. W7 i& M6 Ntry
( v8 J. B% \0 N{
9 G- @9 d! q: f8 k+ @ SP_PROPCHANGE_PARAMS PropChangeParams =
. O9 P* x, ^ ?, O' S- U {sizeof(SP_CLASSINSTALL_HEADER)};
0 R* S7 y/ Y# C8 M$ B8 B1 D# O6 M; a SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
& C! ^; ?2 ` K. b
3 ? X. S) l- v& d hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
- Y( A( z- k& x3 g* l' w
5 g6 |! U1 l" v" A* s // Get a handle to the Selected Item./ \( G* r+ I( R! T7 {9 F
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))6 f5 D; d. ~8 V1 Q
{$ V, ?. f; E& ?* e
FormatMSG(GetLastError(), &lpszMsg);
9 q! ~8 Z8 |6 G throw lpszMsg;
6 g. x4 w+ ^! E! I }+ ?) p# G' J3 N) K* T- a, H2 G
( b% w) n- [ C
// Set the PropChangeParams structure.- H" Y+ J9 Q! Z( g' \! Z5 Q
PropChangeParams.ClassInstallHeader.InstallFunction = 3 J( T* k! O/ v) f& {4 Z
DIF_PROPERTYCHANGE;* \* s8 |6 }* A
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
' M( k5 [3 a! a6 K9 j* a: Q% E PropChangeParams.StateChange = NewStatus;
) q4 \( s6 j' J, s1 U
8 R) m: A9 R- N7 d if (!SetupDiSetClassInstallParams(hDevInfo,( A) N) Z( h3 M. p
&DeviceInfoData,9 @ x. S6 d! K
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,
# w# _% `$ p9 A9 a* @ sizeof(PropChangeParams)))1 e- L9 r- c/ J! d t% H
{; U0 R# C0 H( _# N2 Z' Z
FormatMSG(GetLastError(), &lpszMsg);8 m# @; p ]- G. F5 Y
throw lpszMsg;
* ^3 _0 B, O( |! D# ^. N' q }
( h5 M9 F% ^# G
: c* F' c- Q3 W2 B. z$ H // Call the ClassInstaller and perform the change.
! [3 f6 ~: x5 h S% c% ~" V if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
; Q, e. s' G5 R/ y7 Y* i hDevInfo,
( o9 x$ p, d$ F. A% \0 `) q. |1 v: ` &DeviceInfoData))( O* F4 b2 \; U1 }
{
! L2 G& z5 E% X. u FormatMSG(GetLastError(), &lpszMsg);
, i3 d+ [1 v3 B' b, z' ^ throw lpszMsg;) [( L- m1 i4 W% s1 A$ n
}
4 r4 U0 P) I# e4 \3 j& ~# q* _ R; Z+ D. ^0 K
SetCursor(hCursor); 7 _. q+ J* |3 r6 w; o
return TRUE;% e+ u w( R' U4 n
}; L2 F9 Q$ R+ w5 [
catch (TCHAR * pszError)
' S2 x' o! C- ? J- M+ F{
0 I4 q5 C. J% o+ N SetCursor(hCursor);: N H- C t. N$ g+ @
::MessageBox(NULL,
" J# x$ M! K* N% O7 a8 ~$ z pszError,0 |% ` Y" V! x8 m M, R/ e
_T("提示"),& f. W3 h0 b1 g v7 V
MB_OK);* r" f& F& M/ D1 G5 D% d
if (NULL != lpszMsg)$ p, c8 D% ?! W6 M
{
8 k b5 {6 g" ?. U: h$ k LocalFree((HLOCAL)lpszMsg);, B% h! I' n& c
} $ Y2 c7 Y& Y2 p$ C5 `
return FALSE;
; T' N4 c( S; z9 F}
" ^5 w2 C* y" \) t0 d" J}
7 i3 \$ o5 r; |4 e g" v( Z6 N4 i. y! J
// 这些设备的启用和禁用主要有此函数实现1 g9 z/ n6 r& R( I5 x# r
// 参数说明,nStatus 可取3个值,-1 :啥也不做 M* F& z5 e5 q- I8 X
// 0 禁用设备,1启用设备。
8 V; Y! T) U, k! J% e// nIndex用于控制是对光驱,软驱还是对USB启用或禁用8 s" @0 c7 n- V O! ]3 \
// 也是可取3个值,0 代表软驱,1 代表光驱
( p! t: B9 F9 k// 2 代表USB' j! n+ I) x j, _0 `( m- d
// 譬如要对光驱实现禁用,可以这样调用此函数+ \0 a6 Y( [1 U3 h% H& q$ Q4 c. P
// ControlDisk(0, 1);9 t; |1 P9 G8 `4 z8 Z$ a
BOOL ControlDisk(int nStatus, int nIndex)
% o0 ]2 S/ u8 N7 L{2 N6 ^3 J1 u/ O$ H/ \+ T( P& `* s
if (-1 == nStatus)7 h! U- N8 p/ b
{
9 J& z( Q" [5 d( |: Q2 s, }% K e x return FALSE;: `" ?3 |2 |* Y
} Z" |" F9 g2 ~0 l `! G
/ J, W4 M0 n# s1 DLPTSTR lpszMsg = NULL;) h( d- {) v7 V" ~ k& j
try
& ?- I0 j0 U, W& C- v! f+ Y{1 N/ Q \. p* M" W3 X
TCHAR * GUIDString = NULL;
% Y! k( y! z+ M/ s GUID guid;9 {9 _. o4 l' s" j
ZeroMemory(&guid, sizeof(GUID));
' J2 m4 E, N' [( E, B8 R! F switch(nIndex)' _' L: z' ?4 G- O
{
U: f3 F* \: V8 N+ v/ H. X0 ? case 0: // 0 代表软驱6 q( n! A$ J- g' l4 e1 U! K
GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
1 ~+ S+ h+ _7 q5 U5 _* C2 i UuidFromString((unsigned char *)GUIDString, &guid);8 r9 n# R. D4 \9 @2 u" V
break; 1 z" L* }# K7 Q+ L
case 1: // 1 代表光驱 : H) o ]. S1 \* }7 E2 l5 F2 B' b
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
9 [! k7 K8 z2 M5 e- Q7 d2 ^ p4 @ UuidFromString((unsigned char *)GUIDString, &guid);! p6 L# L0 ]: B" q. w: i2 G/ B7 y
break;
$ r- E: N5 K0 Z7 x7 \ case 2: // 2 代表USB6 o' m( I! u: @4 c
GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
' ^/ ~0 l6 K/ [+ q- r1 u UuidFromString((unsigned char *)GUIDString, &guid);
7 ]: o% ?* H- ?' o7 R* V) J break;
# M: q" ^6 \0 q1 r }7 ^4 v2 } D# F1 Q
1 j+ ~( z, z8 z4 u0 E+ ^' F" w
hDevInfo = SetupDiGetClassDevs(&guid,$ p" k# }1 l, u+ q8 Z8 ^9 D: x
NULL,
0 w/ u# l* O/ D# | NULL,) O2 w- `0 h0 T8 j& I4 X
DIGCF_PRESENT);0 ?: x. M* f; I3 I
if (INVALID_HANDLE_VALUE == hDevInfo)
+ M. S6 [0 g" H2 R$ l- B! _ {
, [* H1 I8 Q% r \3 \( [( P FormatMSG(GetLastError(), &lpszMsg);
! b* Q/ G% W8 v1 e* P) z throw lpszMsg;, J& c' o! a1 V% W4 f
}
( P2 D( t$ q8 l) G" ?- d9 {$ {6 w: `" T
DWORD i;
/ y- T0 t A+ v0 ]+ H0 ?3 v( L SP_DEVINFO_DATA DeviceInfoData;9 W9 c- a, w& |" y
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
S9 A/ U3 o; j, }! \3 w DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);3 J$ I; Y' v6 k0 B# S
$ Z* `$ n0 f5 G4 n* _0 W for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
P8 F0 I' s( S. d9 }5 I {9 Y& n9 T$ q7 k Z
if (1 == nStatus)
. f6 @- h6 L: V {" w% T* O. V( z. j
StateChange(DICS_ENABLE, i, hDevInfo);
3 i8 L {) l- Q+ L7 K8 ` \ }
- g3 \% F+ I! z$ y: V3 d else if (0 == nStatus)
2 {$ U, f+ S. x {
) S# ]' i' t4 b; ^ StateChange(DICS_DISABLE, i, hDevInfo);2 r& m% y4 c- }7 N9 Q; o! {3 W+ R8 A
}
& C8 F8 p% l( ]1 s" a! J& D% _ }! i0 X6 E% f5 j" z w1 A
1 P, \) g$ Q5 U" k& V- M // 释放 device information set
% D& @0 D1 _9 p; F/ { return SetupDiDestroyDeviceInfoList(hDevInfo);$ }* Z. B, }; l% X$ }% n& Z! Z! U
}
P+ o6 V* g, {0 _. {$ zcatch (TCHAR * pszError)
1 l1 ?) Z( v. V5 e e) {& i1 @{
. L R% v. t% f0 f9 v, J+ a- R ::MessageBox(NULL,
6 M* T5 @8 t- B+ R! Q: f pszError,+ a* y2 c7 H5 c" D5 ~' P
_T("提示"),
( {5 P* G2 P% V5 j0 i MB_OK);# ~: i( l9 Q; |8 Q
if (NULL != lpszMsg)
5 ]* h0 W G8 Q2 W {
8 q& ^2 U5 n! I4 {5 ~, }+ O. k/ i2 n LocalFree((HLOCAL)lpszMsg);
/ K& ^) ]6 ^) D& v) G, H. h }
9 | g0 m/ ~% C' g return FALSE;
6 l& e" { `$ Z}
* J4 ^1 l8 ]5 e4 L! Mreturn FALSE;
) ]+ T1 V( b9 y! R2 b* _}
5 W( t+ I. c( U, y5 d9 G
, N$ Y/ r1 ]6 w1 _& n6 F0 Z 经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
8 S! d% A7 P3 N/ u+ J9 @! H 据我观察,在注册表的此项下下:) Q- F8 G; k' y# G; N
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\5 H6 l t% B0 J7 H. \! ?
有很多GUID,每个GUID代表一个设备,譬如这个是USB的
2 b ]# h7 S! `4 T {36FC9E60-C465-11CF-8056-444553540000}& t/ i. X0 I* Z
这个是CDROM的: ] p. l% ~8 n4 ~0 c
{4D36E965-E325-11CE-BFC1-08002BE10318}等等了。/ C' q& j( W" j8 j
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|