IO控制、内核通信
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于visual c++之windows核心编程代码分析(24)IO控制、内核通信
分类:VC++编程技术Visual C++2010编程技术信息安全Visual Studio2012Windows8 2011-12-17
13:06 136人阅读评论(0) 收藏举报我们在进行Windows编程的时候,经常需要进行IO控制与内核通信,我们来实现IO控制与内核通信。
请见代码实现与注释讲解
驱动代码实现与分析
view plaincopy to clipboardprint?
1./* 头文件 */
2.#include <ntddk.h>// 包括了很多NT内核的类型、结构、函数定义,开发驱动时需要
包括此头文件
3.#include <string.h>
4.#include "xioctl.h"
5./* 常量与预定义 */
6.#define NT_DEVICE_NAME L"\\Device\\XIOCTL"
7.#define DOS_DEVICE_NAME L"\\DosDevices\\IoctlTest"
8.
9.#if DBG
10.#define XIOCTL_KDPRINT(_x_) \
11. DbgPrint("XIOCTL.SYS: ");\
12. DbgPrint _x_;
13.#else
14.#define XIOCTL_KDPRINT(_x_)
15.#endif
16.
17./* 函数声明 */
18.NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING Reg
istryPath);
19.NTSTATUS XioctlCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
20.NTSTATUS XioctlDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp );
21.VOID XioctlUnloadDriver(PDRIVER_OBJECT DriverObject );
22.VOID PrintIrpInfo( PIRP Irp );
23.VOID PrintChars( PCHAR BufferAddress, ULONG CountChars );
24.
25.#ifdef ALLOC_PRAGMA
26.#pragma alloc_text( INIT, DriverEntry )
27.#pragma alloc_text( PAGE, XioctlCreateClose)
28.#pragma alloc_text( PAGE, XioctlDeviceControl)
29.#pragma alloc_text( PAGE, XioctlUnloadDriver)
30.#pragma alloc_text( PAGE, PrintIrpInfo)
31.#pragma alloc_text( PAGE, PrintChars)
32.#endif // ALLOC_PRAGMA
33.
34.
35./*************************************
36.* DriverEntry
37.* 功能驱动的入口函数,分配了相关处理例程
38.**************************************/
39.NTSTATUS
40.DriverEntry(
41. IN OUT PDRIVER_OBJECT DriverObject,
42. IN PUNICODE_STRING RegistryPath
43. )
44.{
45. NTSTATUS ntStatus;
46. UNICODE_STRING ntUnicodeString; // 设备名
47. UNICODE_STRING ntWin32NameString; // Win32 设备名
48. PDEVICE_OBJECT deviceObject = NULL; // 设备对象
49.
50.
51. RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );
52. // 创建设备
53. ntStatus = IoCreateDevice(
54. DriverObject, // 驱动对象 DriverEntry 的参
数
55. 0, // 不使用设备扩展
56. &ntUnicodeString, // 设备名 "\Device\XIOCTL"
57. FILE_DEVICE_UNKNOWN, // 设备类型
58. FILE_DEVICE_SECURE_OPEN, //
59. FALSE, //
60. &deviceObject ); // 设备对象
61.
62. if ( !NT_SUCCESS( ntStatus ) )
63. {
64. XIOCTL_KDPRINT(("Couldn't create the device object\n"));
65. return ntStatus;
66. }
67. // 初始化处理例程
68. DriverObject->MajorFunction[IRP_MJ_CREATE] = XioctlCreateClose;//
创建时会调用
69. DriverObject->MajorFunction[IRP_MJ_CLOSE] = XioctlCreateClose;//
关闭时会调用
70. // 处理IO控制
71. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XioctlDeviceC
ontrol;
72. DriverObject->DriverUnload = XioctlUnloadDriver;// 卸载时会调用
73.
74. // WIN32 设备名
75. RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );
76.
77. // 在设备名和WIN32设备名之间创建符号连接
78. ntStatus = IoCreateSymbolicLink(
79. &ntWin32NameString, &ntUnicodeString );
80.
81. if ( !NT_SUCCESS( ntStatus ) )
82. {
83. XIOCTL_KDPRINT(("Couldn't create symbolic link\n"));
84. IoDeleteDevice( deviceObject );
85. }
86.
87. return ntStatus;
88.}
89.
90./*************************************
91.* XioctlCreateClose
92.* 功能驱动对象的处理例程,由DriverEntry指定
93.* 本函数中驱动对象在创建和关闭时调用的例程。
94.* 没有实际的功能,只是将状态设置为成功
95.**************************************/
96.NTSTATUS
97.XioctlCreateClose(
98. IN PDEVICE_OBJECT DeviceObject,
99. IN PIRP Irp
100. )
101.
102.{
103. Irp->IoStatus.Status = STATUS_SUCCESS;
104. Irp->rmation = 0;
105.
106. IoCompleteRequest( Irp, IO_NO_INCREMENT );
107.
108. return STATUS_SUCCESS;
109.}
110.
111./*************************************
112.* XioctlUnloadDriver
113.* 功能卸载驱动时调用的例程,
114.* 删除符号连接,删除设备
115.**************************************/
116.VOID
117.XioctlUnloadDriver(
118. IN PDRIVER_OBJECT DriverObject
119. )
120.
121.{
122. PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; 123. UNICODE_STRING uniWin32NameString;
125. RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
126.
127.
128. // 删除符号连接
129. IoDeleteSymbolicLink( &uniWin32NameString );
130. // 删除设备
131. if ( deviceObject != NULL )
132. {
133. IoDeleteDevice( deviceObject );
134. }
135.}
136.
137./*************************************
138.* XioctlDeviceControl
139.* 功能处理IO控制的例程
140.**************************************/
141.NTSTATUS
142.XioctlDeviceControl(
143. IN PDEVICE_OBJECT DeviceObject,
144. IN PIRP Irp
145. )
146.{
147. PIO_STACK_LOCATION irpSp;// 当前栈的位置
148. NTSTATUS ntStatus = STATUS_SUCCESS;// 执行状态,成功\失败
149.ULONG inBufLength; // 输入缓存大小
150.ULONG outBufLength; // 输出缓存大小
151.PCHAR inBuf, outBuf; // 输入输出缓存
152.PCHAR data = "This String is from Device Driver !!!";
153.ULONG datalen = strlen(data)+1;//输出数据的长度154. PMDL mdl = NULL;
155.PCHAR buffer = NULL;
157. // 处理IRP
158. irpSp = IoGetCurrentIrpStackLocation( Irp );
159. inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLen gth;
160. outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferL ength;
161.
162. if(!inBufLength || !outBufLength)
163. {
164. ntStatus = STATUS_INVALID_PARAMETER;
165. goto End;
166. }
167.
168. // 判断IOCTL
169. switch ( irpSp->Parameters.DeviceIoControl.IoControlCode ) 170. {
171. case IOCTL_XIOCTL_BUFFER:
172. // 显示收到的IRP
173. XIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_BUFFERED\n"));
174. PrintIrpInfo(Irp);
175.
176. // 设备IN OUT 缓存
177. inBuf = Irp->AssociatedIrp.SystemBuffer;
178. outBuf = Irp->AssociatedIrp.SystemBuffer;
179.
180. // 从输入缓存中获得信息
181. XIOCTL_KDPRINT(("\tData from User : %s", inBuf));
182. // 复制数据到输出缓存
183. strncpy(outBuf, data, outBufLength);
184. // 打印输出输出缓存的内容
185. XIOCTL_KDPRINT(("\tData to User : %s", outBuf));
186. // 设置IRP
187. Irp->rmation = (outBufLength<datalen?outBufLe ngth:datalen);
188.
189. break;
190. // 还可以定义其他IO 控制码
191.
192. default:
193.
194. // 处理其他示知的IO code
195. ntStatus = STATUS_INVALID_DEVICE_REQUEST;
196. XIOCTL_KDPRINT(("ERROR: unrecognized IOCTL %x\n",
197. irpSp->Parameters.DeviceIoControl.IoControlCode)); 198. break;
199. }
200.
201.End:
202. // 设备状态,完成IPR处理
203. Irp->IoStatus.Status = ntStatus;
204. IoCompleteRequest( Irp, IO_NO_INCREMENT );
205. return ntStatus;
206.}
207.
208./*************************************
209.* PrintIrpInfo
210.* 功能打印IPR信息
211.**************************************/
212.VOID
213.PrintIrpInfo(
214. PIRP Irp)
215.{
216. PIO_STACK_LOCATION irpSp;
217. irpSp = IoGetCurrentIrpStackLocation( Irp );
218.
219. XIOCTL_KDPRINT(("\tIrp->AssociatedIrp.SystemBuffer = 0x%p\n",
220. Irp->AssociatedIrp.SystemBuffer));
221. XIOCTL_KDPRINT(("\tIrp->UserBuffer = 0x%p\n", Irp->UserBuffer) );
222. XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.Type3Inpu tBuffer = 0x%p\n",
223. irpSp->Parameters.DeviceIoControl.Type3InputBuffer)); 224. XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.InputBuff erLength = %d\n",
225. irpSp->Parameters.DeviceIoControl.InputBufferLength)); 226. XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.OutputBuf ferLength = %d\n",
227. irpSp->Parameters.DeviceIoControl.OutputBufferLength ));
228. return;
229.}
1./* 头文件 */
2.#include <windows.h>
3.#include <winioctl.h>
4.#include <stdio.h>
5.#include <stdlib.h>
6.#include <string.h>
7.#include "..\sys\xioctl.h"
8./* 全局变量 */
9.char OutputBuffer[100];
10.char InputBuffer[100];
11./* 函数声明 */
12.BOOL InstallDriver( SC_HANDLE, LPCTSTR, LPCTSTR );
13.BOOL RemoveDriver( SC_HANDLE, LPCTSTR );
14.BOOL StartDriver( SC_HANDLE , LPCTSTR );
15.BOOL StopDriver( SC_HANDLE , LPCTSTR );
16.
17./*************************************
18.* InstallDriver
19.* 功能创建服务、安装驱动
20.* 参数 SchSCManager,服务控制器句柄
21.* DriverName,服务名
22.* ServiceExe,驱动的可执行程序路径
23.**************************************/
24.BOOL InstallDriver(
25.SC_HANDLE SchSCManager,
26.LPCTSTR DriverName,
27.LPCTSTR ServiceExe
28. )
29.{
30.SC_HANDLE schService;
31.DWORD err;
32.
33. // 调用CreateService创建服务
34. schService = CreateService(SchSCManager, // 服务控制器,SCM句柄
35. DriverName, // 服务名
36. DriverName, // 服务的显示名
37. SERVICE_ALL_ACCESS, // 存取权限
38. SERVICE_KERNEL_DRIVER, // 服务类型
39. SERVICE_DEMAND_START, // 启动类型
40. SERVICE_ERROR_NORMAL, // 启动错误的处理
41. ServiceExe, // 可执行程序
42. NULL, NULL, NULL, NULL, NULL
43. );
44.
45. if (schService == NULL)
46. {
47. // 创建服务失败
48. err = GetLastError();
49. // 服务已经存在
50. if (err == ERROR_SERVICE_EXISTS)
51. {
52. return TRUE;// 返回成功
53. }
54. else
55. {
56. // 输出错误信息,返回失败
57. printf("CreateService failed! Error = %d \n", err );
58. return FALSE;
59. }
60. }
61. // 创建成功,关闭服务
62. if (schService)
63. {
64. CloseServiceHandle(schService);
65. }
66. // 返回成功
67. return TRUE;
68.}
69.
70./*************************************
71.* RemoveDriver
72.* 功能删除驱动服务
73.* 参数 SchSCManager,服务控制器句柄
74.* DriverName,服务名
75.**************************************/
76.BOOL RemoveDriver(
77.SC_HANDLE SchSCManager,
78.LPCTSTR DriverName
79. )
80.{
81.SC_HANDLE schService;
82.BOOLEAN rCode;
83.
84. // 打开服务
85. schService = OpenService(SchSCManager,
86. DriverName,
87. SERVICE_ALL_ACCESS
88. );
89.
90. if (schService == NULL)
91. {
92. // 服务打开失败
93. printf("OpenService failed! Error = %d \n", GetLastError());
94. return FALSE;
95. }
96.
97. // 删除服务
98. if (DeleteService(schService))
99. {
100. rCode = TRUE;
101. }
102. else
103. {
104. //失败
105. printf("DeleteService failed! Error = %d \n", GetLastError ());
106. rCode = FALSE;
107. }
108.
109. // 关闭服务句柄
110. if (schService)
111. {
112. CloseServiceHandle(schService);
113. }
114. return rCode;
115.}
116.
117./*************************************
118.* StartDriver
119.* 功能起动服务,加载执行驱动
120.* 参数 SchSCManager,服务控制器句柄
121.* DriverName,服务名
122.**************************************/
123.BOOL StartDriver(
124.SC_HANDLE SchSCManager,
125.LPCTSTR DriverName
126. )
127.{
128.SC_HANDLE schService;
129.DWORD err;
130.
131. // 打开服务
132. schService = OpenService(SchSCManager,
133. DriverName,
134. SERVICE_ALL_ACCESS
135. );
136. if (schService == NULL)
137. {
138. // 失败
139. printf("OpenService failed! Error = %d \n", GetLastError() );
140. return FALSE;
141. }
142.
143. // 启动服务
144. if (!StartService(schService, // 服务句柄
145. 0, // 参数个数,无
146. NULL // 参数指针,无
147. ))
148. {
149. // 启动失败
150. err = GetLastError();
151. // 已经开始运行
152. if (err == ERROR_SERVICE_ALREADY_RUNNING)
153. {
154. // 返回成功
155. return TRUE;
156. }
157. else
158. {
159. // 失败,打印错误
160. printf("StartService failure! Error = %d \n", err ); 161. return FALSE;
162. }
163. }
164.
165. // 关闭服务句柄
166. if (schService)
167. {
168. CloseServiceHandle(schService);
169. }
170.
171. return TRUE;
172.
173.}
174.
175./*************************************
176.* StopDriver
177.* 功能停止服务,停止驱动运行
178.* 参数 SchSCManager,服务控制器句柄
179.* DriverName,服务名
180.**************************************/
181.BOOL StopDriver(
182.SC_HANDLE SchSCManager,
183.LPCTSTR DriverName
184. )
185.{
186.BOOLEAN rCode = TRUE;
187.SC_HANDLE schService;
188. SERVICE_STATUS serviceStatus;
189.
190. // 打开服务
191. schService = OpenService(SchSCManager,
192. DriverName,
193. SERVICE_ALL_ACCESS
194. );
195.
196. if (schService == NULL)
197. {
198. // 失败
199. printf("OpenService failed! Error = %d \n", GetLastError() );
200. return FALSE;
201. }
202.
203. // 停止运行
204. if (ControlService(schService,
205. SERVICE_CONTROL_STOP,
206. &serviceStatus
207. ))
208. {
209. rCode = TRUE;
210. }
211. else
212. {
213. // 失败
214. printf("ControlService failed! Error = %d \n", GetLastErro r() );
215. rCode = FALSE;
216. }
217.
218. // 关闭服务句柄
219. if (schService)
220. {
221. CloseServiceHandle (schService);
222. }
223. return rCode;
224.
225.}
226.
227./*************************************
228.* GetDriverPath
229.* 功能获得服务驱动的路径
230.* 参数 DriverLocation,返回驱动的路径
231.**************************************/
232.BOOL GetDriverPath(
233.LPSTR DriverLocation
234. )
235.{
236.
237.DWORD driverLocLen = 0;
238.
239. // 驱动.sys文件在本程序同一目标下
240. driverLocLen = GetCurrentDirectory(MAX_PATH,
241. DriverLocation
242. );
243.
244. if (!driverLocLen)
245. {
246. printf("GetCurrentDirectory failed! Error = %d \n", GetLas tError());
247. return FALSE;
248. }
249.
250. // 构造路径,加上驱动名
251. lstrcat(DriverLocation, "\\");
252. lstrcat(DriverLocation, DRIVER_NAME);
253. lstrcat(DriverLocation, ".sys");
254.
255. return TRUE;
256.}
257.
258./*************************************
259.* int _cdecl main( )
260.* 功能加载驱动,进行控制
261.**************************************/
262.int _cdecl main()
263.{
264.HANDLE hDevice;
265.BOOL bRc;
266.ULONG bytesReturned;
267.DWORD errNum = 0;
268.UCHAR driverLocation[MAX_PATH];
269.
270.SC_HANDLE schSCManager;// 服务控制器句柄
271. // 打开服务控制器,后续安装、启动都会使用到。
272. schSCManager = OpenSCManager(NULL, // 本机
273. NULL, // 本机数据库
274. SC_MANAGER_ALL_ACCESS // 存取权限
275. );
276. if (!schSCManager)
277. {
278. // 打开失败
279. printf("Open SC Manager failed! Error = %d \n", GetLastErr or());
280. return 1;
281. }
282. // 获得驱动文件的路径
283. if (!GetDriverPath(driverLocation))
284. {
285. return 1;
286. }
287. // 安装驱动服务
288. if (InstallDriver(schSCManager,
289. DRIVER_NAME,
290. driverLocation
291. ))
292. {
293. // 安装成功,启动服务,运行驱动
294. if(!StartDriver(schSCManager, DRIVER_NAME ))
295. {
296. printf("Unable to start driver. \n");
297. return 1;
298. }
299. }
300. else
301. {
302. // 安装失败,删除驱动。
303. RemoveDriver(schSCManager, DRIVER_NAME );
304. printf("Unable to install driver. \n");
305. return 1;
306. }
307. // 打开驱动,获得控制所用的句柄
308. // 由驱动创建的符号链接
309. hDevice = CreateFile( "\\\\.\\IoctlTest",
310. GENERIC_READ | GENERIC_WRITE,
311. 0,
312. NULL,
313. CREATE_ALWAYS,
314. FILE_ATTRIBUTE_NORMAL,
315. NULL);
316. if ( hDevice == INVALID_HANDLE_VALUE )
317. {
318. printf ( "Error: CreatFile Failed : %d\n", GetLastError()) ;
319. return 1;
320. }
321.
322. // 打印,输入输出。
323. printf("InputBuffer Pointer = %p, BufLength = %d\n", InputBuff er,
324. sizeof(InputBuffer));
325. printf("OutputBuffer Pointer = %p BufLength = %d\n", OutputBuf fer,
326. sizeof(OutputBuffer));
327.
328. // 输入到内核的数据,
329. lstrcpy(InputBuffer,
330. "This String is from User Application; using IOCTL_XIOCTL_ BUFFER");
331. printf("\nCalling DeviceIoControl IOCTL_XIOCTL_BUFFER:\n"); 332.
333. // 清空输出缓存
334. memset(OutputBuffer, 0, sizeof(OutputBuffer));
335. // 进行IO控制,
336. bRc = DeviceIoControl ( hDevice,// 句柄
337. (DWORD) IOCTL_XIOCTL_BUFFER,// IOCTL
338. &InputBuffer,// 输入数据
339. strlen ( InputBuffer )+1,// 输入数据的长度
340. &OutputBuffer,// 输出数据
341. sizeof( OutputBuffer),// 输出数据长度
342. &bytesReturned,// 实际输出的数据长度
343. NULL
344. );
345. // 判断是否成功
346. if ( !bRc )
347. {
348. printf ( "Error in DeviceIoControl : %d", GetLastError());
349. return 1;
350. }
351. // 打印从内核输出的内容
352. printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer);
353. // 关闭句柄
354. CloseHandle ( hDevice );
355. // 停止运行
356. StopDriver(schSCManager,
357. DRIVER_NAME
358. );
359. // 删除服务
360. RemoveDriver(schSCManager,
361. DRIVER_NAME
362. );
363. // 关闭服务控制器
364. CloseServiceHandle (schSCManager);
365. return 0;
366.}
1./* 头文件 */
2.#include <Windows.h>
3.#include <Winioctl.h>
4.#include <stdio.h>
5./* 函数声明 */
6.DWORD EnjectCdrom(LPSTR szCdRomName);
7.DWORD PrintNTFSInfo(LPSTR szVolumeName);
8.
9./*************************************
10.* main
11.* 功能 -cdrom <盘符> 弹出光盘
12.* -ntfs <盘符> 显示nfts分区的信息
13.**************************************/
14.int main(int argc, char* argv[])
15.{
16.CHAR szName[64];
17. if(argc == 3)
18. {
19. // 构造设备名
20. wsprintf(szName, "\\\\.\\%s.", argv[2]);
21. // 弹出光盘
22. if(lstrcmp(argv[1],"-cdrom") == 0)
23. {
24. EnjectCdrom( szName );
25. return 0;
26. }
27. // 获取NTFS分区详细信息
28. if(lstrcmp(argv[1],"-ntfs") == 0)
29. {
30. PrintNTFSInfo( szName );
31. return 0;
32. }
33. }
34. // 使用方法
35. printf("usage: \n\t %s -cdrom <volume>\n\t %s -ntfs <volume>\nlik
e this: \n\t -cdrom G:",
36. argv[0], argv[0]);
37.
38. return 0;
39.}
40.
41./*************************************
42.* DWORD EnjectCdrom(LPSTR szCdRomName)
43.* 功能弹出指定的光盘
44.* 参数 szCdRomName,设备名
45.**************************************/
46.DWORD EnjectCdrom(LPSTR szCdRomName)
48.HANDLE hDevice;
49.DWORD dwBytesReturned;
50.
51. hDevice = CreateFile(szCdRomName, // 设备名
52. GENERIC_ALL, // 存取权限
53. FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 共享方
式
54. NULL, // 默认安全属性
55. OPEN_EXISTING,
56. FILE_ATTRIBUTE_NORMAL,
57. NULL);
58. if (hDevice == INVALID_HANDLE_VALUE)
59. {
60. printf("Could not open file (error %d)\n", GetLastError());
61. return 0;
62. }
63. // 发送IOCTL
64. if(!DeviceIoControl(
65. (HANDLE) hDevice, // 设备句柄
66. IOCTL_STORAGE_EJECT_MEDIA, // 控制码
67. NULL, // 输入缓存
68. 0, // 输入缓存大小
69. NULL, // 输出缓存
70. 0, // 输出缓存大小
71. &dwBytesReturned, // 实际需要的输输入缓存大小
72. NULL // 非OVERLAPPED
73. ))
74. {
75. printf("DeviceIoControl error (%d)",GetLastError());
76. return 0;
77. }
78. return 1;
79.
80.}
82./*************************************
83.* DWORD PrintNTFSInfo(LPSTR szVolumeName)
84.* 功能获取显示指定的NTFS驱动器信息
85.* 参数 szVolumeName,设备名
86.**************************************/
87.DWORD PrintNTFSInfo(LPSTR szVolumeName)
88.{
89. // FSCTL_GET_NTFS_VOLUME_DATA IO控制的返回值保存在
90. // NTFS_VOLUME_DATA_BUFFER结构中
91. NTFS_VOLUME_DATA_BUFFER nvdb;
92.DWORD dwBufferSize;
93.HANDLE hDevice;
94. // 清空参数
95. ZeroMemory(&nvdb,sizeof(nvdb));
96.
97. hDevice = CreateFile(szVolumeName,
98. GENERIC_ALL,
99. FILE_SHARE_READ|FILE_SHARE_WRITE,
100. NULL,
101. OPEN_EXISTING,
102. FILE_ATTRIBUTE_NORMAL,
103. NULL);
104. if (hDevice == INVALID_HANDLE_VALUE)
105. {
106. printf("Could not open file (error %d)\n", GetLastError()) ;
107. return 0;
108. }
109.
110. if(DeviceIoControl(
111. hDevice, // 设备句柄
112. FSCTL_GET_NTFS_VOLUME_DATA, // 控制码
113. NULL, // 输入缓存
114. 0, // 输入缓存大小
115. &nvdb, // 输出缓存
116. sizeof( NTFS_VOLUME_DATA_BUFFER ), // 输出缓存大小
117. &dwBufferSize, // 返回的实际数据大小
118. NULL // 非OVERLAPPED
119. ))
120. {
121. // 打印获取的信息
122. printf("SerialNumber %lu\n",nvdb.VolumeSerialNumber); 123. printf("Starting logical cluster number of the master file table: %lu\n",nvdb.MftStartLcn);
124. printf("Length of the master file table: %lu\n",nvdb.MftVa lidDataLength);
125. printf("... ...\n");
126. }
127. else
128. {
129. printf("DeviceIoControl error: (%d)\n",GetLastError()); 130. return 0;
131. }
132. return 1;
133.}
1./* 头文件 */
2.#include <Windows.h>
3.#include <Winioctl.h>
4.#include <stdio.h>
5./* 函数声明 */
6.DWORD EnjectCdrom(LPSTR szCdRomName);
7.DWORD PrintNTFSInfo(LPSTR szVolumeName);
8.
9./*************************************
10.* main
11.* 功能 -cdrom <盘符> 弹出光盘
12.* -ntfs <盘符> 显示nfts分区的信息
13.**************************************/
14.int main(int argc, char* argv[])
15.{
16.CHAR szName[64];
17. if(argc == 3)
18. {
19. // 构造设备名
20. wsprintf(szName, "\\\\.\\%s.", argv[2]);
21. // 弹出光盘
22. if(lstrcmp(argv[1],"-cdrom") == 0)
23. {
24. EnjectCdrom( szName );
25. return 0;
26. }
27. // 获取NTFS分区详细信息
28. if(lstrcmp(argv[1],"-ntfs") == 0)
29. {
30. PrintNTFSInfo( szName );
31. return 0;
32. }
33. }
34. // 使用方法
35. printf("usage: \n\t %s -cdrom <volume>\n\t %s -ntfs <volume>\nlik
e this: \n\t -cdrom G:",
36. argv[0], argv[0]);
37.
38. return 0;
39.}
40.
41./*************************************
42.* DWORD EnjectCdrom(LPSTR szCdRomName)
43.* 功能弹出指定的光盘
44.* 参数 szCdRomName,设备名
45.**************************************/
46.DWORD EnjectCdrom(LPSTR szCdRomName)
47.{
48.HANDLE hDevice;
49.DWORD dwBytesReturned;
50.
51. hDevice = CreateFile(szCdRomName, // 设备名
52. GENERIC_ALL, // 存取权限
53. FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 共享方
式
54. NULL, // 默认安全属性
55. OPEN_EXISTING,
56. FILE_ATTRIBUTE_NORMAL,
57. NULL);
58. if (hDevice == INVALID_HANDLE_VALUE)
59. {
60. printf("Could not open file (error %d)\n", GetLastError());
61. return 0;
62. }
63. // 发送IOCTL
64. if(!DeviceIoControl(
65. (HANDLE) hDevice, // 设备句柄
66. IOCTL_STORAGE_EJECT_MEDIA, // 控制码
67. NULL, // 输入缓存
68. 0, // 输入缓存大小
69. NULL, // 输出缓存
70. 0, // 输出缓存大小
71. &dwBytesReturned, // 实际需要的输输入缓存大小
72. NULL // 非OVERLAPPED
73. ))
74. {
75. printf("DeviceIoControl error (%d)",GetLastError());
76. return 0;
77. }
78. return 1;
79.
80.}
81.
82./*************************************
83.* DWORD PrintNTFSInfo(LPSTR szVolumeName)
84.* 功能获取显示指定的NTFS驱动器信息
85.* 参数 szVolumeName,设备名
86.**************************************/
87.DWORD PrintNTFSInfo(LPSTR szVolumeName)
88.{
89. // FSCTL_GET_NTFS_VOLUME_DATA IO控制的返回值保存在
90. // NTFS_VOLUME_DATA_BUFFER结构中
91. NTFS_VOLUME_DATA_BUFFER nvdb;
92.DWORD dwBufferSize;
93.HANDLE hDevice;
94. // 清空参数
95. ZeroMemory(&nvdb,sizeof(nvdb));
96.
97. hDevice = CreateFile(szVolumeName,
98. GENERIC_ALL,
99. FILE_SHARE_READ|FILE_SHARE_WRITE,
100. NULL,
101. OPEN_EXISTING,
102. FILE_ATTRIBUTE_NORMAL,
103. NULL);
104. if (hDevice == INVALID_HANDLE_VALUE)
105. {
106. printf("Could not open file (error %d)\n", GetLastError()) ;
107. return 0;
108. }
109.
110. if(DeviceIoControl(
111. hDevice, // 设备句柄
112. FSCTL_GET_NTFS_VOLUME_DATA, // 控制码
113. NULL, // 输入缓存
114. 0, // 输入缓存大小
115. &nvdb, // 输出缓存
116. sizeof( NTFS_VOLUME_DATA_BUFFER ), // 输出缓存大小
117. &dwBufferSize, // 返回的实际数据大小
118. NULL // 非OVERLAPPED
119. ))
120. {
121. // 打印获取的信息
122. printf("SerialNumber %lu\n",nvdb.VolumeSerialNumber); 123. printf("Starting logical cluster number of the master file table: %lu\n",nvdb.MftStartLcn);
124. printf("Length of the master file table: %lu\n",nvdb.MftVa lidDataLength);
125. printf("... ...\n");
126. }
127. else
128. {
129. printf("DeviceIoControl error: (%d)\n",GetLastError()); 130. return 0;
131. }
132. return 1;
133.}。