|
|
(dlutyuanhongl发表于2005-3-15 23:14:04)% C( p) W; N' }8 b+ A4 P- ^
: E. l3 U" {0 z' ?7 P" o
这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:8 T7 i9 R$ m4 x2 p; @) r0 c% L- o
// 必要的头文件和要链接的LIB文件7 I* u" }6 ^6 B( X! h# @9 j
#include <setupapi.h>
) |$ r+ t. g$ M5 {+ L ?#include <shlwapi.h>1 h& S9 r/ S$ ?. Y% T
#pragma comment(lib, "setupapi.lib")
6 h) }0 ~) v, d2 v& `& y0 R#pragma comment(lib, "shlwapi.lib")4 H! L7 Y9 h* c* D U3 f; l8 ~
9 w5 r. m. o, c. V2 E3 E
// device information set(我把它译为设备信息集)
: S: r, a9 S0 U& N. \6 ]$ IHDEVINFO hDevInfo = NULL;3 t. P$ M V& b6 R, r2 U! Q5 S
2 R6 l$ s7 g' V$ P8 \8 j0 s// 出错信息2 o3 _$ Z: g5 M; s% |0 S
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
; f/ S: n; I$ w8 W' u* M{
" v: D5 ^0 L5 o9 k BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 0 w6 e M$ _; }7 [- N, F5 E3 Y6 C
| FORMAT_MESSAGE_ALLOCATE_BUFFER,: l- D R. t; O) l
NULL,2 }3 |( i: Z+ m- l1 c9 ^# m8 b
dwError,) `$ N n9 D4 @( G
MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
% G2 A0 h# h5 X) @' U. s' x (LPTSTR)lpszMsg,
$ Z, i, {" ~. n/ v 0,+ _. S/ [% J: }
NULL);! F0 _/ o/ t- K8 l, Q! |
5 r- K J4 N) I9 x/ G# R- o1 E% m
if (!bOk) d9 \0 W2 k# W# i U" ?. V# H
{# l( U0 G+ H1 b ]
HMODULE hDll = LoadLibraryEx(_T("netmsg.dll")," p. p! {9 k( T' Q9 Q0 u3 W2 W4 \; y
NULL,
2 C- I# K' p, a, \) h% \ DONT_RESOLVE_DLL_REFERENCES);
' B1 ^! \4 e" A1 N5 L$ P if (NULL != hDll)/ z7 [+ C( L! g5 ?$ ~ H& N" i7 u
{& x# z# }+ O8 ]+ T5 K, g
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
B+ c/ R8 }2 X) ^% o* d3 V FORMAT_MESSAGE_FROM_SYSTEM,# s& {+ K) n' A
hDll,* |/ v7 t& p& g' W
dwError,
" L8 j: V1 r! O) ?; v! Z MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
& h, E" H( K. o& x" ~( a1 [0 a (LPTSTR)lpszMsg,
( e# a2 t" H2 P 0, p5 i b+ S; ]% m
NULL);6 e+ J3 O( K+ Y( K
FreeLibrary(hDll);
! C) {7 G2 n4 n4 t7 E }* A! R& |" y- e; ^
}% c. n/ V" r$ N) o* K
}# D5 ?- d4 e ^' N; j- I% n
- b* M8 Y+ m4 P
BOOL ChangeStatus(DWORD NewStatus,
; ^* s2 O4 ?) {1 } DWORD SelectedItem, 7 `$ I9 I, W: X' q+ ]$ A. ^
HDEVINFO hDevInfo)
4 O& K" K! G' j+ j{
0 a, M& _7 k, [LPTSTR lpszMsg = NULL;
" j5 D% W- ]: q5 ~$ YHCURSOR hCursor = NULL;
2 k: C6 Q; y# o# \. s" K; Itry! C0 h8 E: j7 `
{
! S5 j: C* x: W/ B7 H8 O+ f SP_PROPCHANGE_PARAMS PropChangeParams =
+ h: X, K) V: n" U6 x {sizeof(SP_CLASSINSTALL_HEADER)};
( Q+ n z* Q' `, w SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
, A/ C' E+ n2 W( q' k. L5 u' E/ \0 ^7 S
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
% r: {* h) L" B$ G7 o E, e" T3 S$ n* X: U& d
// Get a handle to the Selected Item.9 L; t" h# @7 a3 F2 k
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))+ {- u- m% ^' X
{: R" T( M8 E3 z( A! K9 l5 P( g
FormatMSG(GetLastError(), &lpszMsg);5 {+ ^- V; |$ [' }# @3 d
throw lpszMsg;0 p8 n3 w- a) B1 _* f3 b* l
}* p" I: d: W* Z, f. F j
{. ~, j' e+ d4 {- r& K R' L
// Set the PropChangeParams structure.
2 e0 R+ l, V( e, D PropChangeParams.ClassInstallHeader.InstallFunction = " O5 u! N9 g1 |' ^3 K- T% m ?
DIF_PROPERTYCHANGE;& ?$ v- W& K" Z D/ I* V
PropChangeParams.Scope = DICS_FLAG_GLOBAL;% _% a, M' D' `
PropChangeParams.StateChange = NewStatus;8 |$ W: d, D2 g/ c M
& w3 ?, O$ }1 H: _ if (!SetupDiSetClassInstallParams(hDevInfo,
9 w/ W+ e- q2 f1 E- e &DeviceInfoData,3 [) @& t9 c& H# X1 U5 d
(SP_CLASSINSTALL_HEADER *)& ropChangeParams,0 ^" A7 A1 w* h! L! T& ~
sizeof(PropChangeParams)))/ P- N4 T$ p' }3 t* f3 }
{8 ~; r1 V- c3 `8 F$ s
FormatMSG(GetLastError(), &lpszMsg);6 h) z8 r( |# P4 m+ X; G0 Q
throw lpszMsg;( B: w, }/ F, p/ A
}
( W \1 t* g3 Q0 J2 n9 D% [3 z, s/ s" O
// Call the ClassInstaller and perform the change.
, x0 m* D+ \# N8 r( l) N1 g/ L if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,0 }& x4 w4 z) J! J9 d: _- C6 T: l
hDevInfo,
4 @- a& B1 X/ Q3 a; J' C3 l6 S &DeviceInfoData))" G; J( [8 q" M9 Z% p1 x$ E9 G9 K
{
5 T2 f6 o! z# M6 h# O4 X* { FormatMSG(GetLastError(), &lpszMsg);* w9 _5 L# E; U8 x. s
throw lpszMsg;% d, |4 P/ r4 V' W$ q
}- W5 `+ F; y: E* o
3 b0 y. k1 Y; @4 f+ J3 C6 N
SetCursor(hCursor);
+ I7 t+ U1 H. N$ P2 c/ Q return TRUE;
9 G8 h0 i; A& B}
( ~! s+ x5 b2 [# @* p1 ncatch (TCHAR * pszError)
+ N1 }' w& p9 h) L8 ?0 z3 K2 h{
$ x \- G0 n& R& ]6 r: v SetCursor(hCursor);. p4 W& j6 C: A* |- ?+ b# z
::MessageBox(NULL, o+ _% K6 y S) ~; h' M" b; f
pszError,& F# L& G+ g4 }: U
_T("提示"),& S/ I# }( O2 v4 A
MB_OK);
/ s9 B, L. L, Z- B if (NULL != lpszMsg)
; Q& W1 w: \% A7 p {% o; N; `# x& n4 B s1 A% n' E+ j
LocalFree((HLOCAL)lpszMsg);6 d% ?, z% M r' r) k4 {& h3 |
} : s) ]# O) M6 \! g/ Y
return FALSE;' K! a, o5 A, ~" L1 F& q
}
3 J. ]- [8 ?( ~}
3 E' ~; f, d0 W- o$ W- B% a9 E. K. t2 ^% R
// 这些设备的启用和禁用主要有此函数实现2 Y2 r3 m$ K' K: m% c
// 参数说明,nStatus 可取3个值,-1 :啥也不做' W/ a, @) ]$ Q- F. I( Q) j( i) C
// 0 禁用设备,1启用设备。0 v* W( w2 t" n. t1 N- S
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用9 K( j0 T7 X1 i6 u! G
// 也是可取3个值,0 代表软驱,1 代表光驱
' M; d* B0 R! H& C0 D+ k// 2 代表USB1 K% q$ k- y; E1 U' r1 S
// 譬如要对光驱实现禁用,可以这样调用此函数! I6 @( D: A# U; z! o, J( l
// ControlDisk(0, 1);
6 ^( B. A3 D; i7 s# hBOOL ControlDisk(int nStatus, int nIndex)
* W$ v2 n# B, I{% \/ e/ z, B/ y6 T" Y7 \
if (-1 == nStatus)$ y% {5 \6 _, w2 j# ~' J
{: U6 G% E9 |' r/ S
return FALSE;
9 E) C. a) }; g1 S; G) p3 S. k} ( A' L7 P9 R7 o
) |3 k) [. g! k, T
LPTSTR lpszMsg = NULL;5 \9 p) t6 V8 u
try+ |7 K5 Q- n/ p- |! y; h
{7 x5 {' g" ^- w
TCHAR * GUIDString = NULL;
p$ B! {0 e8 U# g GUID guid;
5 n) h+ H# Q5 g* F z3 q2 q7 E ZeroMemory(&guid, sizeof(GUID));' m9 P4 M& }# e) U, N4 V/ O
switch(nIndex)
# A3 e: N7 [, k {+ C P5 g' h, m( C- w
case 0: // 0 代表软驱
7 _3 D+ E* w" d& h! T GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");7 [8 F+ ]* R) b
UuidFromString((unsigned char *)GUIDString, &guid);
: I( J$ R* \+ j break;
3 c2 K5 s% O! Y [) y1 R% W9 P case 1: // 1 代表光驱 9 |% s# b @* o
GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
# I7 i- W% w K. {% R! y UuidFromString((unsigned char *)GUIDString, &guid);- j k8 o! l' J8 K. _
break;
/ c' Q7 H) J" L; c4 D/ |1 `* l$ W case 2: // 2 代表USB
( V: M+ R: M u; w% Y2 J6 } GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
. J3 L8 _: A" U: { UuidFromString((unsigned char *)GUIDString, &guid);
J7 x9 `! w/ C4 u: R C break;0 M0 o0 j" ^ z2 E3 N) r. Q
}
' n0 ^$ o% [* w ~, I$ |1 ~3 \
+ {) d+ ]# u7 P hDevInfo = SetupDiGetClassDevs(&guid,
' K# g# r! r' {& e" |% @: b NULL,
; j/ m( v) e; ^( B! N NULL,# l7 p- H( w: I; V' J
DIGCF_PRESENT);- Q: l8 @7 x8 j6 n$ m$ d
if (INVALID_HANDLE_VALUE == hDevInfo)
! S1 Z6 W. C$ I {
9 M* }. D* e3 O/ |% ]5 C" \: q FormatMSG(GetLastError(), &lpszMsg);
/ @7 n6 N+ x1 K( p; p1 j* q throw lpszMsg;% l- j4 d& ]1 @! @6 b- o
}! }+ u! T7 m/ L* Y& Z$ a
0 s2 F, ^3 n6 U! C( ~, ~ DWORD i;
. A+ e3 S0 y* t0 J6 m/ S$ ] SP_DEVINFO_DATA DeviceInfoData;
) c% A: E" b" b* \6 Z! t* w ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
. z& G- C9 V- |9 t% |1 o! ` DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);) D- Z, j/ M! r$ i
2 T! I1 x" k5 `3 c3 {; O- g3 g8 x% t
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)$ S' O2 D+ {' `" r# _- a; q
{
* V6 M; A& Y: H3 f5 c9 W4 @ if (1 == nStatus)6 m! b8 s& D; @: A. w2 `
{
$ o; f" m! e. _ StateChange(DICS_ENABLE, i, hDevInfo);, {1 F0 L6 e& _& ~+ i/ ?9 _
}, K% X8 s$ c. F0 ]8 ^; x
else if (0 == nStatus)0 c4 X9 k. M$ \9 _- Z/ p5 _6 m
{- S" R% }& o- y/ V* o
StateChange(DICS_DISABLE, i, hDevInfo);
( N& E' n! ~7 q2 R# G }
, x0 [. I0 _; _. g4 G }4 j! ^- S8 z" W) n& B6 F$ L% l% e
9 k" x$ X7 [; Z9 ]: M: x
// 释放 device information set
0 }6 h# A/ s! C \ return SetupDiDestroyDeviceInfoList(hDevInfo);+ B" z6 B: g" P+ Y7 N9 M. R2 |- n6 X
}
b( c2 n) J6 g3 K& d, vcatch (TCHAR * pszError)/ L) M( e6 d- C; L& e# j; P
{
3 Y, J& N! H1 t! j- T, R8 V s ::MessageBox(NULL,' j0 ?6 ?5 W1 }- M" M7 H4 j; U# b
pszError,
- d& S [$ t8 z/ s, S. l1 V _T("提示"),
# {$ b# o* F% B# z# D0 f0 B) D MB_OK);
m( A) K* _7 ]6 C3 U% [ if (NULL != lpszMsg)
5 t1 o4 x; H$ T; @( R {6 @0 l) g2 B, w3 Q& m* \+ ^/ K
LocalFree((HLOCAL)lpszMsg);! ]) T1 K8 A& P' E4 n$ M
} 7 d9 j6 A: W: R* e% ?7 K, c ]) j
return FALSE;! T& f7 f3 {: y n% t$ x" l/ i
}9 D- c1 C! H e( y' ]- F- P
return FALSE;8 d6 p% N, G) _, z+ G" ~; c. f
}
) c& e/ {! l2 T8 T: m- }( D2 K, k1 A# O/ W* D3 B
经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。' S, j* Y2 ]+ }
据我观察,在注册表的此项下下:
/ [+ J7 n& Q; a3 y) g3 O HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\' D6 {& e" f, g# o
有很多GUID,每个GUID代表一个设备,譬如这个是USB的8 Y7 X5 I) x* A' r
{36FC9E60-C465-11CF-8056-444553540000}# m) N0 Y8 \/ z$ Y s7 @, M$ S
这个是CDROM的
2 C1 {2 V1 W5 s9 }' Q {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。4 V% Q% S! |" g! B* N' C2 x% f
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。 |
|