📄 enumdisk.c
字号:
/*++
Copyright (c) 1990-2000 Microsoft Corporation, All Rights Reserved
Module Name:
Enumdisk.c
Abstract:
Please note that the objective of this sample is to demonstrate the
techniques used. This is not a complete program to be used in
commercial product.
The purpose of the sample program is to enumerates all available disk
devices and get the device property. It uses IOCTL_STORAGE_QUERY_PROPERTY
to get the Bus and Device properties. It also opens the handle to the device
and sends a SCSI Pass Through command.
See SDK & DDK Documentation for more information about the APIs,
IOCTLs and data structures used.
Author:
Raju Ramanathan 05/15/2000
Notes:
Revision History:
Raju Ramanathan 05/29/2000 Completed the sample
--*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <windows.h>
#include <initguid.h> // Guid definition
#include <devguid.h> // Device guids
#include <setupapi.h> // for SetupDiXxx functions.
#include "cfgmgr32.h" // for SetupDiXxx functions.
#include <devioctl.h>
#include <ntdddisk.h>
#include <ntddscsi.h>
#include <enumdisk.h>
VOID DebugPrint( USHORT DebugPrintLevel, PCHAR DebugMessage, ... )
/*++
Routine Description:
This routine print the given string, if given debug level is <= to the
current debug level.
Arguments:
DebugPrintLevel - Debug level of the given message
DebugMessage - Message to be printed
Return Value:
None
--*/
{
va_list args;
va_start(args, DebugMessage);
if (DebugPrintLevel <= DebugLevel) {
char buffer[128];
(VOID) vsprintf(buffer, DebugMessage, args);
printf( "%s", buffer );
}
va_end(args);
}
int __cdecl main()
/*++
Routine Description:
This is the main function. It takes no arguments from the user.
Arguments:
None
Return Value:
Status
--*/
{
HDEVINFO hDevInfo, hIntDevInfo;
DWORD index;
BOOL status;
hDevInfo = SetupDiGetClassDevs(
(LPGUID) &GUID_DEVCLASS_DISKDRIVE,
NULL,
NULL,
DIGCF_PRESENT ); // All devices present on system
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("SetupDiGetClassDevs failed with error: %d\n", GetLastError() );
exit(1);
}
//
// Open the device using device interface registered by the driver
//
//
// Get the interface device information set that contains all devices of event class.
//
hIntDevInfo = SetupDiGetClassDevs (
(LPGUID)&DiskClassGuid,
NULL, // Enumerator
NULL, // Parent Window
(DIGCF_PRESENT | DIGCF_INTERFACEDEVICE // Only Devices present & Interface class
));
if( hDevInfo == INVALID_HANDLE_VALUE ) {
printf("SetupDiGetClassDevs failed with error: %d\n", GetLastError() );
exit(1);
}
//
// Enumerate all the disk devices
//
index = 0;
while (TRUE)
{
printf("Properties for Device %d", index+1);
status = GetRegistryProperty( hDevInfo, index );
if ( status == FALSE ) {
break;
}
status = GetDeviceProperty( hIntDevInfo, index );
if ( status == FALSE ) {
break;
}
index++;
}
printf("\r *** End of Device List *** \n");
SetupDiDestroyDeviceInfoList(hDevInfo);
SetupDiDestroyDeviceInfoList(hIntDevInfo);
return 0;
}
BOOL GetRegistryProperty( HDEVINFO DevInfo, DWORD Index )
/*++
Routine Description:
This routine enumerates the disk devices using the Setup class interface
GUID GUID_DEVCLASS_DISKDRIVE. Gets the Device ID from the Registry
property.
Arguments:
DevInfo - Handles to the device information list
Index - Device member
Return Value:
TRUE / FALSE. This decides whether to continue or not
--*/
{
SP_DEVINFO_DATA deviceInfoData;
DWORD errorCode;
DWORD bufferSize = 0;
DWORD dataType;
LPTSTR buffer = NULL;
BOOL status;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
status = SetupDiEnumDeviceInfo(
DevInfo,
Index,
&deviceInfoData);
if ( status == FALSE ) {
errorCode = GetLastError();
if ( errorCode == ERROR_NO_MORE_ITEMS ) {
DebugPrint( 2, "No more devices.\n");
}
else {
printf("SetupDiEnumDeviceInfo failed with error: %d\n", errorCode );
}
return FALSE;
}
//
// We won't know the size of the HardwareID buffer until we call
// this function. So call it with a null to begin with, and then
// use the required buffer size to Alloc the necessary space.
// Keep calling we have success or an unknown failure.
//
status = SetupDiGetDeviceRegistryProperty(
DevInfo,
&deviceInfoData,
SPDRP_HARDWAREID,
&dataType,
(PBYTE)buffer,
bufferSize,
&bufferSize);
if ( status == FALSE ) {
errorCode = GetLastError();
if ( errorCode != ERROR_INSUFFICIENT_BUFFER ) {
if ( errorCode == ERROR_INVALID_DATA ) {
//
// May be a Legacy Device with no HardwareID. Continue.
//
return TRUE;
}
else {
printf("SetupDiGetDeviceInterfaceDetail failed with error: %d\n", errorCode );
return FALSE;
}
}
}
//
// We need to change the buffer size.
//
buffer = LocalAlloc(LPTR, bufferSize);
status = SetupDiGetDeviceRegistryProperty(
DevInfo,
&deviceInfoData,
SPDRP_HARDWAREID,
&dataType,
(PBYTE)buffer,
bufferSize,
&bufferSize);
if ( status == FALSE ) {
errorCode = GetLastError();
if ( errorCode == ERROR_INVALID_DATA ) {
//
// May be a Legacy Device with no HardwareID. Continue.
//
return TRUE;
}
else {
printf("SetupDiGetDeviceInterfaceDetail failed with error: %d\n", errorCode );
return FALSE;
}
}
printf("\n\nDevice ID: %s\n",buffer );
if (buffer) {
LocalFree(buffer);
}
return TRUE;
}
BOOL GetDeviceProperty(HDEVINFO IntDevInfo, DWORD Index )
/*++
Routine Description:
This routine enumerates the disk devices using the Device interface
GUID DiskClassGuid. Gets the Adapter & Device property from the port
driver. Then sends IOCTL through SPTI to get the device Inquiry data.
Arguments:
IntDevInfo - Handles to the interface device information list
Index - Device member
Return Value:
TRUE / FALSE. This decides whether to continue or not
--*/
{
SP_DEVICE_INTERFACE_DATA interfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData = NULL;
STORAGE_PROPERTY_QUERY query;
PSTORAGE_ADAPTER_DESCRIPTOR adpDesc;
PSTORAGE_DEVICE_DESCRIPTOR devDesc;
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
HANDLE hDevice;
BOOL status;
PUCHAR p;
UCHAR outBuf[512];
ULONG length = 0,
returned = 0,
returnedLength;
DWORD interfaceDetailDataSize,
reqSize,
errorCode,
i;
interfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
status = SetupDiEnumDeviceInterfaces (
IntDevInfo, // Interface Device Info handle
0, // Device Info data
(LPGUID)&DiskClassGuid, // Interface registered by driver
Index, // Member
&interfaceData // Device Interface Data
);
if ( status == FALSE ) {
errorCode = GetLastError();
if ( errorCode == ERROR_NO_MORE_ITEMS ) {
DebugPrint( 2, "No more interfaces\n" );
}
else {
printf("SetupDiEnumDeviceInterfaces failed with error: %d\n", errorCode );
}
return FALSE;
}
//
// Find out required buffer size, so pass NULL
//
status = SetupDiGetDeviceInterfaceDetail (
IntDevInfo, // Interface Device info handle
&interfaceData, // Interface data for the event class
NULL, // Checking for buffer size
0, // Checking for buffer size
&reqSize, // Buffer size required to get the detail data
NULL // Checking for buffer size
);
//
// This call returns ERROR_INSUFFICIENT_BUFFER with reqSize
// set to the required buffer size. Ignore the above error and
// pass a bigger buffer to get the detail data
//
if ( status == FALSE ) {
errorCode = GetLastError();
if ( errorCode != ERROR_INSUFFICIENT_BUFFER ) {
printf("SetupDiGetDeviceInterfaceDetail failed with error: %d\n", errorCode );
return FALSE;
}
}
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -