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

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

[复制链接]
发表于 2005-3-16 11:27:43 | 显示全部楼层 |阅读模式
  (dlutyuanhongl发表于2005-3-15 23:14:04)6 n- ?$ l3 `6 g0 n% Z6 D

0 K; z4 U: {0 g' A这几天,由于工作的实际需要,需要对光驱,软驱,USB的启用和禁用实现控制。参考大家提供的对网卡禁用的代码,实现了光驱,软驱,USB的启用和禁用。主要实现代码如下:9 m! M1 d/ A' O, I6 Q6 r1 t0 B3 o
// 必要的头文件和要链接的LIB文件
$ c+ x/ w& O+ {' c6 d#include <setupapi.h>
, D$ P7 k8 x. f( Y3 P& g#include <shlwapi.h>& g! G: ^3 i, Y. g: @" A. W/ M
#pragma comment(lib, "setupapi.lib")
" q  i& P3 J' K+ t#pragma comment(lib, "shlwapi.lib")
- D8 p$ H5 H/ v. g1 @
  W9 E' s$ k; O& |# g// device information set(我把它译为设备信息集)0 P8 u! v  A' E: d& [$ A
HDEVINFO hDevInfo = NULL;7 j  \$ h* |' E9 Y* n
$ ^( V2 M- H" @0 T+ g
// 出错信息- [* }$ I: v8 l
void FormatMSG(DWORD dwError, LPTSTR * lpszMsg)& J9 o/ t$ N$ u8 B5 _$ u. M
{   t4 f1 Y( f$ s9 L9 V
   BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM ! F9 u% h9 N* \# u6 G' M
       | FORMAT_MESSAGE_ALLOCATE_BUFFER,
# v9 B8 Y0 V: I- _        NULL,* [. u; r  O8 n; K9 K% z
       dwError," }+ F+ X8 q1 T! b) x3 w0 X
       MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),+ {; N/ g( |' g
       (LPTSTR)lpszMsg,0 |: K( {. W  G4 L
       0,$ e+ H% H1 Q; |! q# w
       NULL);, o* P) p8 H- j7 l6 ^- {: y" b

6 M6 s3 q3 Z+ ^if (!bOk)8 ?, r# {8 w; c/ ]$ i
{$ H* N: }/ _0 R& r4 I& B, Z
    HMODULE hDll = LoadLibraryEx(_T("netmsg.dll"),' \7 C/ _, T- w' P' T
                                 NULL,
9 ~+ u, C' r  ~& }% F  B                                  DONT_RESOLVE_DLL_REFERENCES);' L0 ?) {/ h! y- `; V5 b( a
  if (NULL != hDll)
- |' K/ D- Z" h# x" b/ d  {
8 G$ M. r7 S9 S: ]   FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |  
$ b4 g' }( V0 B. F3 n6 ~% ^                 FORMAT_MESSAGE_FROM_SYSTEM,
1 n) `$ i" P; h) E# I                 hDll,
8 S; G" w' ?  Q/ ]                 dwError,
% C  I7 `1 B; U1 e( c# E1 X. H        MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
& N; D! N0 j7 h/ V$ l                 (LPTSTR)lpszMsg,. x1 z, c, o# u( a7 I
                0,
' u; V$ J  W) S" u                 NULL);
8 ~/ y/ I* G: ^/ c  s      FreeLibrary(hDll);. {9 U  o! j' T' y
  }6 a+ O5 ]4 e. l8 {
}: S) G. E0 \' k6 O( p& Z
}" R, V  v7 c# I! g& E! S

, c6 p3 \- c/ c. Q0 @BOOL ChangeStatus(DWORD NewStatus,
& q4 ]5 D* Y" X                  DWORD SelectedItem,   + A' D0 _. p. j* T  d! ?' B6 p, ^# q
                 HDEVINFO  hDevInfo)8 W. P0 x  p1 G- h0 G( N
{; t* X/ n2 F( I( L
LPTSTR lpszMsg = NULL;
1 p/ |" {9 F5 T# I6 h% IHCURSOR hCursor = NULL;
, f; y3 L& T. ]: {  ztry% L$ l" T9 F2 x0 Y9 X
{
9 {8 g7 ^4 `  [! X( \( ]  SP_PROPCHANGE_PARAMS PropChangeParams = 2 f( ^' p5 q( }3 S( \0 X
                    {sizeof(SP_CLASSINSTALL_HEADER)};) G/ s5 q4 X- W# ?+ [# g9 R
  SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};    
5 w$ Y& z# k  ]& V0 h' y* W3 H4 o  B; |
  hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));0 I" G: V+ G+ {; t' I7 B/ ]( m
6 d% L6 d& Z- [2 [# p4 H0 q9 n2 w
  // Get a handle to the Selected Item.
; k- d) W8 x. i, ~4 d- _  if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData)). F/ \1 _. y$ J1 Q* w9 }
  {* K) D0 A7 m0 o* S
      FormatMSG(GetLastError(), &lpszMsg);
# i2 k0 y: w' \       throw lpszMsg;' k* k+ `# I3 q) ^
  }) J; J4 X' }; ]) k+ K1 v1 P* }0 @
, ]2 n/ s, W0 T% _# b6 c4 ]
  // Set the PropChangeParams structure.9 x) I( s9 Q3 K
  PropChangeParams.ClassInstallHeader.InstallFunction =   8 O# @4 N# h9 D2 k, Q
                                    DIF_PROPERTYCHANGE;" s0 Q! w6 ^# f
  PropChangeParams.Scope = DICS_FLAG_GLOBAL;. D' C, Z9 N" h6 `  i! @
  PropChangeParams.StateChange = NewStatus;
6 x  ]( v8 @5 O  ^. P
. w. G& {4 o4 d- f  if (!SetupDiSetClassInstallParams(hDevInfo,/ A7 c3 q8 a, k: r
           &DeviceInfoData,
7 C  r) ?' H6 I2 z0 R            (SP_CLASSINSTALL_HEADER *)&ropChangeParams,
$ N% |/ H+ m* F$ k            sizeof(PropChangeParams)))
3 @0 W+ Z+ v* R3 s1 \  {5 T5 a& g- F0 v
  FormatMSG(GetLastError(), &lpszMsg);- b* G( y2 Y% @2 f! ~0 u
  throw lpszMsg;$ |3 x0 L+ \$ T/ M) }# k3 c
  }- E! J6 E4 }1 t5 ]( }+ ~

/ ~* v1 ?: D  S9 y) A8 P6 g/ V  // Call the ClassInstaller and perform the change.( M( H1 `1 o( E7 D% R
  if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
8 n" ^* m' D) t( Y0 k% b            hDevInfo,6 _, }; \6 i" J7 [$ d7 l
           &DeviceInfoData))
. W5 Z3 e( P' M  t+ K  H  {# q- I) n2 J9 s  n7 g* x# y
  FormatMSG(GetLastError(), &lpszMsg);
* i0 l1 ]# ]4 A   throw lpszMsg;8 E9 l' e' v4 w/ o
  }
7 B2 p' c7 D( z( G8 i
1 N. K7 P& N  @1 {7 ~4 O+ A( L  SetCursor(hCursor);  9 S0 I2 M+ M: w
  return TRUE;4 n& Q$ J8 E7 A4 E) `* f0 ?
}) I4 ~. U' |1 {+ `9 r, D
catch (TCHAR * pszError)2 |: C1 \# h6 o4 @
{  `5 \5 k# Q4 F9 D. a$ H! d
  SetCursor(hCursor);7 {' Q, o# v& V* q4 W8 w
  ::MessageBox(NULL,! C4 g& s" H; y( x& T# Y
              pszError,. K! m5 O, E& x  \- ?! c
              _T("提示"),
! R# o7 F! |6 @- B2 ~7 Q4 S9 E               MB_OK);
4 F! b* E" S, G0 p: W! t& v4 p  if (NULL != lpszMsg)  c/ k: c  Z6 X. s8 t
  {
: m5 a  q1 C( B1 r& L- a% \       LocalFree((HLOCAL)lpszMsg);
; F3 P& T0 \% b2 V$ @/ Y8 D  } " b  K8 }( N, p" e, e$ r
     return FALSE;
* x, M- y9 p- n8 o}     
: e' `. w% D9 l' G- x% d5 b- h}% E3 b4 z( s7 g- l

( q( f9 ^- v: X1 F// 这些设备的启用和禁用主要有此函数实现1 ^, C- M  k. ^  e3 b- Z5 O
// 参数说明,nStatus 可取3个值,-1 :啥也不做
. ?) D& g0 J! S  w( A( ^// 0 禁用设备,1启用设备。
! N: N5 z0 w/ ?5 X6 T, l: _& i6 z// nIndex用于控制是对光驱,软驱还是对USB启用或禁用% \' ?, t5 t5 P& D4 Q) h
// 也是可取3个值,0 代表软驱,1 代表光驱
3 X% s4 p8 T, J+ n1 c/ a// 2 代表USB1 ^' j' ?9 d8 [9 |% v
// 譬如要对光驱实现禁用,可以这样调用此函数
& b  @$ k" u/ Z// ControlDisk(0, 1);8 e4 j9 Q$ v! _: o1 F7 S, o8 z
BOOL ControlDisk(int nStatus, int nIndex)5 r" a7 T7 L8 [6 m) f$ N& Q$ ]1 Y) f
{
: w) b) o% r+ j& B) Dif (-1 == nStatus)
$ W6 P- D, N  w; u( C{
! y) x0 {$ M& B  return FALSE;7 ?2 @0 q/ |% s+ s- r
} # E0 _1 c$ ], d) r
# _1 n% p" V: n( H. B
LPTSTR lpszMsg = NULL;
. W! K7 Y& J! Y5 z, E! {try
  h. j- x- i. r0 [{6 v+ F: j7 l2 G+ A
  TCHAR * GUIDString = NULL;+ m$ p5 g/ k/ v0 J9 d5 z
  GUID guid;: z8 J7 u6 i' o) B$ Z8 Y% k3 M& F
  ZeroMemory(&guid, sizeof(GUID));) W, R" c- m- \! q3 p! @
  switch(nIndex)
6 p2 s  V0 M3 b, o: C( R  {
# d' O# ^: b" R6 K  case 0:    // 0 代表软驱
) F. P0 r8 [5 O5 N% F   GUIDString = _T("4D36E980-E325-11CE-BFC1-08002BE10318");
3 D, h( B0 l# S* U   UuidFromString((unsigned char *)GUIDString, &guid);
5 ?: m7 f3 j' p* \   break;
/ G: y. x) K0 D6 `4 F  case 1:    // 1 代表光驱 ) H. o: o; ]3 r+ W7 [
  GUIDString = _T("4D36E965-E325-11CE-BFC1-08002BE10318");5 P: f" L) [# y% z9 P# A+ U
  UuidFromString((unsigned char *)GUIDString, &guid);; v- N3 g" o) F/ I' Y$ ~. `
  break;
" ~4 P3 Y% `. X! f2 M8 O- x2 h  case 2:    // 2 代表USB, W. G% f' a$ q! Y
  GUIDString = _T("36FC9E60-C465-11CF-8056-444553540000");
' E7 W; E+ O$ U, @   UuidFromString((unsigned char *)GUIDString, &guid);. p! n( O' P6 X- m
  break;
5 m+ d6 b) S0 X' \  }
% K6 H* D: l, \- _% M4 c4 |
) Y+ K! l( p( H1 A" W6 t% }  hDevInfo = SetupDiGetClassDevs(&guid,
6 v4 i" {/ _7 Y; Q& r! l  T            NULL,( ]2 ?( L  W3 p5 J# u; \; P
           NULL,
( T. O/ _) Y; V5 O% G! K            DIGCF_PRESENT);- s- u8 U0 ?+ m# c. G2 K$ _  x+ @% ?# ~
  if (INVALID_HANDLE_VALUE == hDevInfo)
0 q' @0 v4 K; h- ?# ?  {) \# \% r* }% ]" ~/ v# ?
  FormatMSG(GetLastError(), &lpszMsg);
, g2 C0 n! Q5 P; @, m; y   throw lpszMsg;  M5 N) l# v$ W0 [2 @% a
  }2 p1 V' c: B$ U0 C) O

" f9 ?) l: o- j) ?0 Q% Q, J  DWORD i;
( p! L+ d# `# P* |: q& E. o  SP_DEVINFO_DATA DeviceInfoData;
" H% D: I: P, X' d3 D8 V  ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
4 j- q& P( ~3 S" w0 h* w- M1 Q  DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
" B1 }& j: }5 b4 l" H, E1 S: b& ~4 B; v$ ^! Z& t) h. C$ W2 [
  for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
# O( M  m% L$ a- t  {
' w# z  r; B! H* d9 C- p5 R   if (1 == nStatus)* Q! x  F  F' [) h
  {0 n/ P  Z: D# O  w2 ^+ N
   StateChange(DICS_ENABLE, i, hDevInfo);
2 _# j: y: f( l   }
. a- c# z4 @: B+ t# Q, p   else if (0 == nStatus)
+ J. @$ p5 M; x3 K& p   {' P" r& E: P7 N: g- q
   StateChange(DICS_DISABLE, i, hDevInfo);
9 h7 T9 p" s1 [   }   6 Y9 L7 s  a: V+ E' H6 s/ f# X* f
  }  A- }2 H& ]6 x9 L! p9 i. V

+ X2 u0 u; L+ U, h- h6 ^  // 释放 device information set
1 `) e9 g) @+ K3 b: l- o. X8 o  return SetupDiDestroyDeviceInfoList(hDevInfo);
# q! F: O8 H( o, ^}
/ k7 y6 b  a3 `catch (TCHAR * pszError)0 g$ B8 o6 R, j' Y6 b6 |. z! m# `5 P
{' i1 C' c! b$ O$ H8 \' l: }
  ::MessageBox(NULL,6 A" r$ f! M! ^) J; f
           pszError,+ H5 t) r) @7 F& ~8 R4 y
          _T("提示"),
5 ~, ^3 z) I' C7 j) C5 O      MB_OK);
4 `* U& \) p% Y0 f0 N! e+ C  if (NULL != lpszMsg)
# n! J* t( |  O" b  {* I, [3 S, H6 W# f/ K; X; S
  LocalFree((HLOCAL)lpszMsg);
& H( s; y1 ^; I  I! N4 d  }
1 Z$ _* w8 \, g) [5 A  return FALSE;
- n, x7 ^9 u) n# S9 r& \* i7 {}
5 ?! d7 C2 m# Nreturn FALSE;
- q% }& V( g- N  |7 u9 P, X}
( [. p" k6 l- G2 B5 n( y
2 D5 p' B! |+ P# j5 C( c' H  H    经测试这样对光驱,软驱和USB实现禁用没有问题,但是当禁用过之后如果要对USB实现启用必须两次调用ControlDisk(1, 2);这个函数才可,其余的两个启用没什么问题。还有要说的就是我不是用的枚举所有的设备,然后再过滤(网上的那个禁用网卡的就是这种方法)。( r# `/ H9 B$ ^. Z; b: v! \
   据我观察,在注册表的此项下下:
: J  y/ z, r) i    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
8 {/ |5 B1 z2 b5 S6 {    有很多GUID,每个GUID代表一个设备,譬如这个是USB的
. o; `  q* M: I" i2 q% G    {36FC9E60-C465-11CF-8056-444553540000}
) Z% H+ `% i# D" M; i/ V    这个是CDROM的  P9 x8 V6 \) q' _/ u9 o/ ~
   {4D36E965-E325-11CE-BFC1-08002BE10318}等等了。- R5 Y% e; y' l
这些值你即使把它改为别的GUID,我使用原来的GUID仍然可以实现我的功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 20:01 , Processed in 0.016728 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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