找回密码
 注册
搜索
查看: 4118|回复: 0

[转载]光驱,软驱,USB的禁用和启用

[复制链接]
发表于 2005-3-16 11:27:43 | 显示全部楼层 |阅读模式
  (dlutyuanhongl发表于2005-3-15 23:14:04)& O& w/ v+ H& t4 y- Q$ J$ p

( p( c6 R7 i% @  |6 ~) v这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:
, v! |) L$ z; a9 P// 必要的头文件和要链接的LIB文件
3 t+ V# m$ y; S0 t* p#include <setupapi.h>
# U% c( g! ~7 b, d6 l" \#include <shlwapi.h>
1 N& ]6 m4 j+ g# e( W  ^#pragma comment(lib, "setupapi.lib")! w6 P9 j1 S: @+ i. F7 i: |; H: T
#pragma comment(lib, "shlwapi.lib")" @' Z. _" A2 t! Y6 q

3 y) G# y. ]6 R% s1 ~8 o) l// device information set(我把它译为设备信息集)8 v9 B; N) C7 V" h7 p. d
HDEVINFO hDevInfo = NULL;. R# E- C. D, R6 \8 N
1 D) r4 R' c8 X- I' {# {8 z1 {
// 出错信息% Y  \! A) }+ [3 ?( Z2 l0 _' g" o: x6 I
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)
1 o7 C& B! Z# z$ {6 [5 I+ G# H8 F{ 1 W. ~, j0 h2 u- @! R- B
   BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
' q$ u4 ?6 A) E+ G- n        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
) `$ t5 @3 W: b* @0 g        NULL,
5 d- E( r5 g) j6 z% g+ p        dwError,/ T+ n4 H, y# ?- c: v' O9 S' T
       MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
( \! R/ p6 R; Q7 T        (LPTSTR)lpszMsg,# ?7 q% _/ X0 M6 \7 |
       0,
. }8 @# ]( t5 b) B  I% f% @6 d        NULL);; P3 E4 y3 j* G
0 m0 E# d2 g! {" K2 x% \; B
if (!bOk): A! A; ~1 `* f
{
, D# [; `" A+ N7 w# ]! |* [     HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),6 h0 k4 C9 ~" `; K. ^
                                 NULL,: i& s) V4 T$ t7 T- C3 O" f8 q
                                 DONT_RESOLVE_DLL_REFERENCES);4 A9 j/ t) X3 \  e* {' w( d
  if (NULL != hDll)
3 t) M' q; S6 _  {
, F. j* \0 u7 H+ W1 K   FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |   ' n8 ^# k6 X/ W2 z' D! N
                FORMAT_MESSAGE_FROM_SYSTEM,* W  b4 }8 @, Q* O+ Z3 k- ^- q
                hDll,
! {! C9 Y1 o. `* q/ R, i9 t                 dwError,% r& s1 \# p( E9 s7 [" S
       MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),. Y7 a; G2 T$ r6 F' ]
                (LPTSTR)lpszMsg,
7 J& ~9 e$ D9 E                 0,- g; p5 t) S9 z4 Q
                NULL);
, f" c( i' Y0 [; K) J% O! I) v      FreeLibrary(hDll);2 S# `8 K' ^0 J! `4 I" m+ ^8 T
  }9 h- C3 C5 ?3 }* e" S/ x/ G
}
( W2 u2 x, F7 P. d* o% z! n}
% E( e# j9 t& k" d. y$ X/ ]
6 v+ ~, F3 z5 M4 p8 Z/ K8 |- ]BOOL ChangeStatus(DWORD NewStatus, 4 G' Q% O0 Y" R% ~2 V4 l. m0 \
                 DWORD SelectedItem,  
( I# p- y5 t( O+ G                  HDEVINFO  hDevInfo)
9 X1 e* X  ]2 @7 y" q) y{
7 T/ c) f5 s1 W' sLPTSTR lpszMsg = NULL;8 X9 @2 [5 {8 n& f  u+ c3 K: D
HCURSOR hCursor = NULL;' o1 l6 a4 z5 u6 P
try0 @$ S6 {5 D/ p, F
{  H+ f% }+ w' X0 S: n) E
  SP_PROPCHANGE_PARAMS PropChangeParams =
, ~) ~  b4 z  h2 n. S- h6 @                     {sizeof(SP_CLASSINSTALL_HEADER)};+ V5 d* [  s/ \9 \+ x
  SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};    
8 D5 X1 G; d" q5 v. @/ x" ?9 k" C' V/ m) L* ^! G2 C
  hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
& v. M7 y' c4 e! b4 Z& v% P" ~3 T- P/ `( J7 ]
  // Get a handle to the Selected Item., X# ^9 Q- y: ^3 m
  if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))1 f# a3 O9 N, ^6 l% r5 m' \
  {# M* j2 j8 Y1 \' z3 b3 y# a
      FormatMSG(GetLastError(), &lpszMsg);
( \8 P9 m' l1 c6 ~       throw lpszMsg;9 m1 t  y" }' \
  }. ?- P. |% X: |

; c( J. J& j$ x1 X  // Set the PropChangeParams structure.
  h# k! ^4 F  f) u0 X# D  PropChangeParams.ClassInstallHeader.InstallFunction =   ) }( P3 @& y- }( ~$ K- I
                                    DIF_PROPERTYCHANGE;; f7 ^4 }' Y+ a6 A1 l
  PropChangeParams.Scope = DICS_FLAG_GLOBAL;( E+ i6 O# u6 s8 T! |* g
  PropChangeParams.StateChange = NewStatus;- d8 j5 Y$ Q5 N+ Y* B* R1 Z

2 l5 _$ G6 E- A  if (!SetupDiSetClassInstallParams(hDevInfo,- N$ i/ w% ]! r4 U
           &DeviceInfoData,
! O4 f5 v& u4 P8 v8 U            (SP_CLASSINSTALL_HEADER *)&ropChangeParams,* P" S( m8 l- V: k0 ]& u$ m
           sizeof(PropChangeParams)))' w8 P2 V  q* ^* |4 d. x3 O! L
  {  k0 h' Q# T5 c0 z. q2 R
  FormatMSG(GetLastError(), &lpszMsg);# m0 a( Y* V, W' D) C( ~
  throw lpszMsg;
! Z! r# q1 ^7 L! a9 K$ v5 ?# L  }7 R; F3 N* ?) P5 V9 D# t7 t/ Q
3 t" \" A( f7 Z5 x
  // Call the ClassInstaller and perform the change.
1 A8 h) e+ y0 I  X: r% V- X. z: ~  if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,# V8 v7 t4 G7 C
           hDevInfo,
' n7 B) |9 r0 x) A+ b            &DeviceInfoData))' V3 N7 B, @' R
  {; p% z% q" Q9 l( ]# R; F
  FormatMSG(GetLastError(), &lpszMsg);
; T; Z) J7 h# h0 h( E   throw lpszMsg;
% {' z7 k, H- w: D9 H" O  }
# N1 K  @# o1 c7 e8 V3 k- P0 L3 i* c' U" U. j
  SetCursor(hCursor);  
1 I% A" \. @2 X; g, I) @) s  return TRUE;
$ U- \8 q9 o, n}4 e: \* F: u8 W
catch (TCHAR * pszError)
, E7 j+ p! U2 J{% y  g3 |, ?; h$ `* }0 r* l
  SetCursor(hCursor);
& a6 A9 k/ i1 H  G) c4 _4 [  ::MessageBox(NULL,2 r1 O; o% _# r& ~2 u. ?
              pszError,
* r) i( z9 U5 s: O) _               _T("提示"),& i* _2 A: Y) g# u! L4 _: V% H
              MB_OK);1 ]+ y; p7 p* K$ c# J+ j, x% g
  if (NULL != lpszMsg)
# s7 b. l5 t& B7 y; T: k9 x, _  {/ x" i& B) V, {  |0 m9 |
      LocalFree((HLOCAL)lpszMsg);, f  F& F& Z& z) {% F2 J" F0 P
  }
/ r& G+ _  Z3 s( r; p# m0 S      return FALSE;6 j! E8 d9 B) ~7 a# Z$ Q
}     
3 t9 [8 w- k- a/ j4 F6 c}
$ f' O! ~% x& n0 _& H7 L
3 e0 V2 F3 Z9 R1 _, R// 这些设备的启用和禁用主要有此函数实现
; h9 a5 m% ?- g; i7 o- z" ]4 x6 t// 参数说明,nStatus 可取3个值,-1 :啥也不做+ s( Y, P7 o( L2 J) l  `
// 0 禁用设备,1启用设备。' R5 ^! i% d' z4 u
// nIndex用于控制是对光驱,软驱还是对USB启用或禁用3 A+ f. ]1 R3 Q8 A$ g5 B
// 也是可取3个值,0 代表软驱,1 代表光驱
+ ^8 C! P: T2 M% g3 {; y( O// 2 代表USB
4 i' V( `" }( Y2 l: ^: w0 z0 s// 譬如要对光驱实现禁用,可以这样调用此函数0 \7 `$ u' p% Y1 I' |6 s1 s9 B
// ControlDisk(0, 1);. y$ U2 x% O: _
BOOL ControlDisk(int nStatus, int nIndex)7 s  U  r8 V6 A/ D# O  O+ z% p; o8 K' n
{4 y$ Z" z6 n; U0 b: g9 F* y
if (-1 == nStatus)
% h; p4 a& _9 P6 f1 H1 ]% E$ M{
$ ~  r1 l, H$ S) Z, {5 }6 h8 [) N  return FALSE;5 Z! j8 G; v$ s1 U5 k% H4 J! c
}
2 h0 x5 a& g' _. a% g
0 B8 M1 z/ T/ X0 tLPTSTR lpszMsg = NULL;0 s* ~. Y) V4 n* J( D
try- u( B, ^! I: S
{
' r4 \* b* _4 _2 [& r6 m  b$ K% \  TCHAR * GUIDString = NULL;: ^% [$ K' F( F: T& Z2 ~
  GUID guid;  z8 d8 v3 E/ }3 V  }
  ZeroMemory(&guid, sizeof(GUID));) S5 [0 C9 a- v- v
  switch(nIndex)4 K& \1 U/ d6 l2 a* ?
  {. D  M- S0 R7 b; Y' t) g" F+ x
  case 0:    // 0 代表软驱. K4 L8 D0 |0 q6 B9 X
  GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
5 }3 v- M  R# {+ h. y* L/ v   UuidFromString((unsigned char *)GUIDString, &guid);
  j! [6 e/ o/ N" v   break; " b  \! c* k, m2 q) F) h
  case 1:    // 1 代表光驱 8 U$ ^1 b( x& Q2 s
  GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");
  T3 i  ^; @. I! h% E5 O. M6 d; y   UuidFromString((unsigned char *)GUIDString, &guid);  l6 F% R; n& c! F( h5 n) @
  break;
; w4 Z6 P" E$ l- q  case 2:    // 2 代表USB6 Y6 ^* ?8 U" J/ u- u( w
  GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");6 l; M, a3 O% ~9 g0 Z
  UuidFromString((unsigned char *)GUIDString, &guid);
! r8 [3 e$ Y6 B& _: Y; b8 D2 |   break;
' R. ]3 F& l+ X: L7 B& D  }# [! w: G( k7 e5 {0 Z3 ~8 M
( A8 g) b# o( V/ U! l
  hDevInfo = SetupDiGetClassDevs(&guid,1 W. N) [) K* U* W1 f; y; V) }, R
           NULL,, s6 y9 v( q  G* g/ _( r: a
           NULL,$ O- }. p7 V/ @0 Z
           DIGCF_PRESENT);' m$ }+ ^# u; P1 ], E9 _" N
  if (INVALID_HANDLE_VALUE == hDevInfo)
2 O6 L) V* e0 ^1 e, l  {  x& P2 v; R. p
  FormatMSG(GetLastError(), &lpszMsg);! a+ G1 V6 }0 p6 I
  throw lpszMsg;
1 b; D* f- f2 n# J' V; U8 U# C/ g  }2 I. v: M6 _) o/ E2 C; s' _5 [

  k4 C2 {0 ~; A; h6 i2 Z  DWORD i;
6 i0 P+ w4 f1 Z! r  SP_DEVINFO_DATA DeviceInfoData;0 |* G0 \$ {% j5 ]/ M9 J
  ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
6 X0 ?1 T) L# Z7 V4 ~+ c5 I  DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  h1 d* C  ^: L1 s2 Z4 V8 V/ |- g. ~/ `
  for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)- Z; m5 ?; D* U3 Y. H% b
  {: o& W! }( i8 ]4 T1 z$ K. y% h" G
  if (1 == nStatus)- @6 t( E+ m2 [  v- U
  {7 H! _2 T6 d% j5 I9 L3 a
   StateChange(DICS_ENABLE, i, hDevInfo);# g% R" s, S6 U; Y
  }
) \( U$ \# w4 n3 {, r   else if (0 == nStatus)
; H6 h& V3 ^3 ?! o# O5 C   {
8 j8 m7 J2 N) Y8 k& |: Y% ~+ q    StateChange(DICS_DISABLE, i, hDevInfo);  m' R$ e) r: U6 L0 s
  }   ( q# w0 B7 I8 `" D2 s0 b/ U6 ]- [2 r
  }
6 K% b7 W* g7 A0 G! Y& a% B/ j& J' v( E
  // 释放 device information set
/ o. j. j3 s6 a2 _9 A% J  return SetupDiDestroyDeviceInfoList(hDevInfo);& I7 E* S  d2 w* w# l0 W: c. F
}; y% M) f$ `7 I
catch (TCHAR * pszError)
) I3 n6 t, w- F  V{
4 K# p: Z7 [+ x: J7 A0 g( @  ::MessageBox(NULL,
0 x. R3 e% d: ^$ C8 |+ z            pszError,
6 ^2 [  N+ T3 d  z) N           _T("提示"),! J1 P2 b: Y$ J- F  C  i' X
     MB_OK);
+ G- R( M. K/ R) I, {5 v+ }  if (NULL != lpszMsg)9 K* P4 |- m: e- k( w
  {$ C: Q! k$ E* _# o: }5 T
  LocalFree((HLOCAL)lpszMsg);
! [$ q0 _# y* x5 R$ M; G7 N7 l  }
& _% b/ f7 w. [% h  return FALSE;0 F! q" J+ z( x% t
}
8 ^  u0 `  v- |+ ^/ Y- |return FALSE;
1 g! ?) [9 u  u1 Y! X! N5 |}/ {4 g! k+ O/ G4 I+ z* ^+ i
5 E+ p  i1 [9 j* ?1 ?8 e
   经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。
$ d# H. @& ]2 _( _7 o    据我观察,在注册表的此项下下:4 P( q: R  S7 c6 |, @# S
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\( v- _# `  M# F  |; \
   有很多GUID,每个GUID代表一个设备,譬如这个是USB的
# p# A' T( X" a; U- ?) S7 A    {36FC9E60-C465-11CF-8056-444553540000}$ H1 N; [) ]) S  n; ^' ^
   这个是CDROM的
5 ?" F: j! d+ @5 _7 g/ V1 w( T0 L! O    {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。
% f$ ~( W+ _) N' O. _7 F5 q% B这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-5-2 11:47 , Processed in 0.018809 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表