How to use deviceiocontrol function properly - c

This is my code:
Code:
HANDLE HandelUsb= CreateFile(L"\\\\.\\G:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (HandelUsb == INVALID_HANDLE_VALUE)
{
printf("Terminal failure: Unable to open usb ERROR CODE:0x%x\n", GetLastError());
return 1;
}
DISK_GEOMETRY d = { 0 };
DWORD dwReturned = 0;
int gs =DeviceIoControl(HandelUsb, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &d, sizeof(DISK_GEOMETRY),&dwReturned, NULL);
printf("%d\n", gs);
if (d.MediaType == RemovableMedia)
{
DWORD dwReturned2 = 0;
MEDIA_SERIAL_NUMBER_DATA data={ 0 };
if (DeviceIoControl(HandelUsb, IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, NULL, 0, &data,sizeof(MEDIA_SERIAL_NUMBER_DATA), &dwReturned2, NULL)) {
printf("SerialNumberLength %d\nResult %d\nReserved[2] %s\nSerialNumberData[1] %s ", data.SerialNumberLength, data.Result, data.Reserved, data.SerialNumberData);
}
else {
printf("faild to get serial number ERROR CODE:0x%x\n", GetLastError());
}
}
CloseHandle(HandelUsb);
return 0;
Everything works well except for the function
Code:
DeviceIoControl(HandelUsb, IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, NULL, 0, &data,sizeof(MEDIA_SERIAL_NUMBER_DATA), &dwReturned2, NULL)
It always fails (returns a value of 0), GetLastError returns the value 0X1 (problem function).
Maybe someone here can show me what I'm missing here?
Following the comment of #IInspectable ,i changed the code to it:
//volume handle to device handle
VOLUME_DISK_EXTENTS volumeToDevice = { 0 };
DWORD Returned = 0;
DeviceIoControl(HandelToUsb,IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,NULL,0,&volumeToDevice,sizeof(VOLUME_DISK_EXTENTS),&Returned,NULL);
WCHAR volume[150] ;
swprintf_s(volume, L"\\\\.\\PhysicalDrive%d", volumeToDevice.Extents[0].DiskNumber);
wprintf(L"%s\n", volume);
//handle to phisicalDrive
HANDLE HandelUsb = CreateFile(volume, 0, FILE_SHARE_READ |FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
DWORD dwReturned2 = 0;
MEDIA_SERIAL_NUMBER_DATA data={ 0 };
if (DeviceIoControl(HandelUsb, IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, NULL, 0, &data,sizeof(MEDIA_SERIAL_NUMBER_DATA), &dwReturned2, NULL)) {
printf("SerialNumberLength %d\nResult %d\nReserved[2] %s\nSerialNumberData[1] %s ", data.SerialNumberLength, data.Result, data.Reserved, data.SerialNumberData);
}
else {
printf("faild to get serial number ERROR CODE:0x%x\n", GetLastError());
}
I still get a failure 0X1 on function
DeviceIoControl (Handel Usb, IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, NULL, 0, & data, sizeof (MEDIA_SERIAL_NUMBER_DATA), & dwReturned2, NULL)
I ran Windus 7
i tried to Change the permissions function CreateFile (Add GENERIC_EXECUTE , replace to GENERIC_ALL add FILE_ATTRIBUTE_NORMAL ), play with the parameters of the DeviceIoControl.

Related

Memory Mapped File changes not reflected in underlying file

I am learning MMF in win32 C.
I can't seem to see what I am missing...
Here is my code:
#include "stdafx.h"
#include <Windows.h>
int main()
{
wchar_t szfilename[] = L"c:\\temp\\mmf.txt";
HANDLE hFile = CreateFile(
szfilename,
GENERIC_READ | GENERIC_WRITE, //dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, //dwShareMode
NULL, //lpSecurityAttributes
CREATE_NEW, //dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, //dwFlagsAndAttributes
NULL); //hTemplateFile
if (hFile == INVALID_HANDLE_VALUE)
{
DWORD error = GetLastError();
if (error != ERROR_FILE_EXISTS)
exit(-1);
}
//Now create the file mapping
HANDLE hMap = CreateFileMapping(
hFile,
NULL, //LPSECURITY_ATTRIBUTES lpAttributes,
PAGE_READWRITE, //DWORD flProtect,
0, //DWORD dwMaximumSizeHigh,
1024, //DWORD dwMaximumSizeLow,
L"myMappingFile"); //LPCTSTR lpName
if (hMap == (HANDLE)ERROR_ALREADY_EXISTS || hMap == NULL)
{
DWORD error = GetLastError();
exit(-2);
}
LPCTSTR pBuf = (LPTSTR)MapViewOfFile(hMap, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
0);
if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n",
GetLastError());
return -2;
}
wchar_t szMsg[] = L"Msg from first process";
CopyMemory((PVOID)pBuf, szMsg, wcslen(szMsg) * sizeof(wchar_t));
UnmapViewOfFile(pBuf);
CloseHandle(hMap);
CloseHandle(hFile);
return 0;
}
I open a file, associate it with a memory mapping and create a view. Then I write data (copy) into the buffer (view) and close things down.
I am trying to figure out why my underlying file (c:\temp\mmf.txt) does not contain the msg after the routine executes. Am I missing something? The file size remains 0.
Here is a snippet of code that demonstrates memory mapping a file. In the end I think you will just benefit from reading the MSDN docs for each API call you are using a little more carefully.
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hFileMapping = NULL;
LPVOID pBase = NULL;
__try
{
hFile = CreateFile(filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile == INVALID_HANDLE_VALUE) __leave;
hFileMapping = CreateFileMapping(hFile,
NULL,
PAGE_READONLY,
0, 0, NULL);
if(hFileMapping == NULL) __leave;
pFileBase = MapViewOfFile(hFileMapping,
FILE_MAP_READ,
0, 0, 0);
if(pBase == NULL) __leave;
}
__finally
{
if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
if(hFileMapping != NULL) CloseHandle(hFileMapping);
}

receive ip frames using ndisuio

I'm writing a DHCP client for Windows ce. after doing it all with sockets I realized that I coudn't send packets from ip 0.0.0.0 so I found that I need to use NDISUIO.
After googling about NDISUIO I can send working DHCP Discovery Packets BUT I can't receive the server response ( the program gets stuck waiting for packets). Note that I can see them in wireshark.
int cUDP::Start()
{
char MensajeLog[256];
char buff[1024];
TCHAR pDevName[1024];
TCHAR pDevBuf[1024];
PNDISUIO_QUERY_BINDING pQueryBinding;
ULONG ulData;
NDISUIO_SET_OID set_oid;
//NDISUIO_QUERY_OID query_oid;
//El ethernet type para el protocolo IP es 0x0800
USHORT uEther =0x0800;
//###########################################################
if(m_hAdapter == INVALID_HANDLE_VALUE)
m_hAdapter = CreateFile(
NDISUIO_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);
if(m_hAdapter == INVALID_HANDLE_VALUE || m_hAdapter == NULL)
{
m_iLastError = CUDP_SOCKET_ERROR;
return 1;
}
pQueryBinding = (PNDISUIO_QUERY_BINDING) buff;
pQueryBinding->BindingIndex = 0;
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_QUERY_BINDING,
pQueryBinding,
sizeof(NDISUIO_QUERY_BINDING),
NULL,
1024,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 2;
}
else
{
memset(pDevName,0,1024);
memcpy(pDevName,&buff[pQueryBinding->DeviceNameOffset], pQueryBinding->DeviceNameLength);
}
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_OPEN_DEVICE,
pDevName,
wcslen(pDevName)*sizeof(TCHAR),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 3;
}
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_SET_ETHER_TYPE,
&uEther,
sizeof(uEther),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 5;
}
ulData = NDIS_PACKET_TYPE_ALL_LOCAL|NDIS_PACKET_TYPE_BROADCAST|NDIS_PACKET_TYPE_PROMISCUOUS;
set_oid.Oid = OID_GEN_CURRENT_PACKET_FILTER;
CopyMemory(&set_oid.Data[0], &ulData,sizeof(ulData));
set_oid.ptcDeviceName = pDevName;
if(!DeviceIoControl( m_hAdapter,
IOCTL_NDISUIO_SET_OID_VALUE,
&set_oid,
sizeof(set_oid),
NULL,
0,
&m_dwReturnedBytes,
NULL))
{
CloseHandle(m_hAdapter);
return 6;
}
return 0;
};
int cUDP::ReceiveFrame ( BYTE* pBuffer,
DWORD Timeout_ms )
{
int timeout;
int timepoint;
DWORD pdwReadBytes;
socklen_t SendAddrlen = sizeof(m_SendAddr);
int BufferLen = sizeof(IPHeaderFormat) +
sizeof(UDPHeaderFormat) +
sizeof (DHCPMsgFormat);//sizeof (DHCPMsgFormat);
timepoint = GetTickCount();
do
{
timeout = GetTickCount();
{
if(!ReadFile( m_hAdapter,
pBuffer,
0,
NULL,
NULL))
{
m_iLastError = CUDP_RECEIVING_ERROR;
}
}
}while(((unsigned) (timeout - timepoint) < Timeout_ms));
return m_iLastError;
};
Anyone can push me in the right direction? thanks in advance
After reading and searching a lot, I found that the problem was on the call to DeviceIoControl with IOCTL_NDISUIO_SET_ETHER_TYPE. It turns out that uEther must be in network byte order so changing this variable to uEther = 0x0008; will do the trick.

How to extend a volume programmatically

My requirement is to extend drive volume through program. When I used IOCTL_DISK_GROW_PARTITION in DeviceIO to extend it, the disk management shows the new modified size while the size of the drive in This PC (My Computer) remains unchanged.
BOOL DeviceIoControl(
(HANDLE) hDevice, // handle to device
IOCTL_DISK_GROW_PARTITION, // dwIoControlCode
(LPVOID) lpInBuffer, // input buffer
(DWORD) nInBufferSize, // size of the input buffer
NULL, // lpOutBuffer
0, // nOutBufferSize
(LPDWORD) lpBytesReturned, // number of bytes returned
(LPOVERLAPPED) lpOverlapped // OVERLAPPED structure
);
Through some analysis I found that while using this API the MBR of the disk is modified but the cluster bitmap of drive is not changed. I want to know the correct way of using this DeviceIO to expand a volume or some other API to do the same process.
need understand different between disk driver, which maintain info about disk layout and partitions (it size, offset from disk begin, style (gpt or mbr) ) and file system, which mount this partition.
IOCTL_DISK_GROW_PARTITION - this ioctl is handled by disk driver and extend partition, but this can not have effect for file system, which not handle this ioctl and have no knowledge at all that partition was extended. so you need additional ioctl use FSCTL_EXTEND_VOLUME - this ioctl already send and handle to file-system.
so if we have to do next steps
send IOCTL_DISK_GROW_PARTITION with
DISK_GROW_PARTITION as input buffer
send IOCTL_DISK_UPDATE_DRIVE_SIZE with DISK_GEOMETRY
as output buffer
send IOCTL_DISK_GET_PARTITION_INFO_EX with
PARTITION_INFORMATION_EX as output for get actual size of
partition now.
calculate new size of the volume, in sectors
LONGLONG SectorsPerPartition = PartitionEntry->PartitionLength.QuadPart / dg.BytesPerSector;
(dg we got at step 2 and PartitionEntry at step 3)
finally use FSCTL_EXTEND_VOLUME
full code can be like next
int __cdecl SortPartitions(PPARTITION_INFORMATION_EX PartitionEntry1, PPARTITION_INFORMATION_EX PartitionEntry2)
{
if (!PartitionEntry1->PartitionNumber) return PartitionEntry2->PartitionNumber ? -1 : 0;
if (!PartitionEntry2->PartitionNumber) return +1;
if (PartitionEntry1->StartingOffset.QuadPart < PartitionEntry2->StartingOffset.QuadPart) return -1;
if (PartitionEntry1->StartingOffset.QuadPart > PartitionEntry2->StartingOffset.QuadPart) return +1;
return 0;
}
DWORD ExtendTest(HANDLE hDisk)
{
STORAGE_DEVICE_NUMBER sdn;
ULONG dwBytesRet;
if (!DeviceIoControl(hDisk, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesRet, NULL))
{
return GetLastError();
}
if (sdn.DeviceType != FILE_DEVICE_DISK || sdn.PartitionNumber != 0)
{
return ERROR_GEN_FAILURE;
}
GET_LENGTH_INFORMATION gli;
if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), &dwBytesRet, NULL))
{
return GetLastError();
}
DbgPrint("Disk Length %I64x (%I64u)\n", gli.Length.QuadPart, gli.Length.QuadPart);
PVOID stack = alloca(guz);
union {
PVOID buf;
PDRIVE_LAYOUT_INFORMATION_EX pdli;
};
ULONG cb = 0, rcb, PartitionCount = 4;
for (;;)
{
if (cb < (rcb = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[PartitionCount])))
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, buf, cb, &dwBytesRet, NULL))
{
if (PartitionCount = pdli->PartitionCount)
{
PPARTITION_INFORMATION_EX PartitionEntry = pdli->PartitionEntry;
qsort(PartitionEntry, PartitionCount, sizeof(PARTITION_INFORMATION_EX),
(int (__cdecl *)(const void *, const void *))SortPartitions );
do
{
if (!PartitionEntry->PartitionNumber)
{
continue;
}
LARGE_INTEGER EndOffset;
LARGE_INTEGER MaximumOffset = PartitionCount != 1 ? (PartitionEntry + 1)->StartingOffset : gli.Length;
EndOffset.QuadPart = PartitionEntry->StartingOffset.QuadPart + PartitionEntry->PartitionLength.QuadPart;
if (EndOffset.QuadPart > MaximumOffset.QuadPart)
{
//??
__debugbreak();
}
else if (EndOffset.QuadPart < MaximumOffset.QuadPart)
{
DISK_GROW_PARTITION dgp;
dgp.PartitionNumber = PartitionEntry->PartitionNumber;
dgp.BytesToGrow.QuadPart = MaximumOffset.QuadPart - EndOffset.QuadPart;
WCHAR sz[128];
swprintf(sz, L"\\\\?\\GLOBALROOT\\Device\\Harddisk%d\\Partition%u", sdn.DeviceNumber, dgp.PartitionNumber);
HANDLE hPartition = CreateFile(sz, FILE_READ_ACCESS|FILE_WRITE_ACCESS, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hPartition != INVALID_HANDLE_VALUE)
{
// +++ begin extend
BOOL fOk = FALSE;
DISK_GEOMETRY dg;
if (DeviceIoControl(hPartition, IOCTL_DISK_GROW_PARTITION, &dgp, sizeof(dgp), 0, 0, &dwBytesRet, 0) &&
DeviceIoControl(hPartition, IOCTL_DISK_UPDATE_DRIVE_SIZE, 0, 0, &dg, sizeof(dg), &dwBytesRet, 0) &&
DeviceIoControl(hPartition, IOCTL_DISK_GET_PARTITION_INFO_EX, 0, 0, PartitionEntry, sizeof(*PartitionEntry), &dwBytesRet, 0)
)
{
LONGLONG SectorsPerPartition = PartitionEntry->PartitionLength.QuadPart / dg.BytesPerSector;
fOk = DeviceIoControl(hPartition, FSCTL_EXTEND_VOLUME, &SectorsPerPartition,
sizeof(SectorsPerPartition), 0, 0, &dwBytesRet, 0);
}
if (!fOk)
{
GetLastError();
}
//--- end extend
CloseHandle(hPartition);
}
}
// else EndOffset.QuadPart == MaximumOffset.QuadPart - partition can not be extended
} while (PartitionEntry++, --PartitionCount);
}
return NOERROR;
}
switch (ULONG err = GetLastError())
{
case ERROR_MORE_DATA:
PartitionCount = pdli->PartitionCount;
continue;
case ERROR_BAD_LENGTH:
case ERROR_INSUFFICIENT_BUFFER:
PartitionCount <<= 1;
continue;
default:
return err;
}
}
}
DWORD ExtendTest()
{
HANDLE hDisk = CreateFileW(L"\\\\?\\PhysicalDrive0", FILE_GENERIC_READ|FILE_GENERIC_WRITE,
FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hDisk != INVALID_HANDLE_VALUE)
{
DWORD err = ExtendTest(hDisk);
CloseHandle(hDisk);
return err;
}
return GetLastError();
}

SCSI Read(10) on a Physical Drive on Windows

I tried issuing a SCSI Read(10) command to a physical drive on a Windows 7 machine. Below is the code snippet that I am using. It is failing with error code 87.
void scsi_read()
{
const UCHAR cdb[10] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 512, 0 };
UCHAR buf[512];
BYTE senseBuf[196];
const int SENSE_LENGTH = 196;
LPCSTR fname = "\\\\.\\E:";
HANDLE fh;
DWORD ioctl_bytes;
DWORD err = 0;
SCSI_PASS_THROUGH s = {0};
memcpy(s.Cdb, cdb, sizeof(cdb));
s.CdbLength = 10;
s.DataIn = SCSI_IOCTL_DATA_IN;
s.TimeOutValue = 30;
s.Length = sizeof(SCSI_PASS_THROUGH);
s.ScsiStatus = 0x00;
s.SenseInfoOffset = senseBuf;
s.SenseInfoLength = SENSE_LENGTH;
s.DataBufferOffset = buf;
s.DataTransferLength = 512;
fh = CreateFile("\\\\.\\E:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(fh == INVALID_HANDLE_VALUE) {
printf("Could not open %s file, error %d\n", fname, GetLastError());
return (FALSE);
}
int ret = DeviceIoControl(fh,IOCTL_SCSI_PASS_THROUGH, &s,sizeof(s), //scsiPassThrough.sizeof,
&s,
sizeof(s),
&ioctl_bytes,
NULL);
printf("ret %d",(int)ret);
if (ret==1) {
printf("OK");
}
else {
err = GetLastError();
printf("Last error code %u\n", err);
printf("Return size %d\n", ioctl_bytes);
printf("Sense data\n");
int i=0;
for (i = 0; i < 20; i++) {
printf("\t%x", senseBuf[i]);
}
printf("\n");
}
CloseHandle(fh);
}
Error: Hex dumps are printed in the output
you got error code 87 - ERROR_INVALID_PARAMETER because code totally wrong.
for example:
const UCHAR cdb[10] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 512, 0 };
but 512 is > 255 (MAXUCHAR) are you not got compiler warning here ?
warning C4305: 'initializing': truncation from 'int' to 'const UCHAR'
look at this line !
s.DataBufferOffset = buf;
from SCSI_PASS_THROUGH structure:
DataBufferOffset
Contains an offset from the beginning of this structure to the data
buffer. The offset must respect the data alignment requirements of the
device.
so offset to buffer, not pointer to buffer
for use this correct you code need be like this:
struct MY_DATA : SCSI_PASS_THROUGH
{
UCHAR buf[512];
} s;
s.DataBufferOffset = FIELD_OFFSET(MY_DATA, buf);
but better use SCSI_PASS_THROUGH_DIRECT with IOCTL_SCSI_PASS_THROUGH_DIRECT
you hardcode sector size (512), when need get it at runtime. and how you initialize CDB ?!? at all unclear what you try todo.
working code example (sorry but on c++ instead c)
#define _NTSCSI_USER_MODE_
#include <scsi.h>
#include <ntddscsi.h>
BOOL scsi_read(HANDLE fh, PVOID buf, DWORD cb, ULONGLONG LogicalBlock, ULONG TransferBlocks)
{
SCSI_PASS_THROUGH_DIRECT s = {
sizeof(SCSI_PASS_THROUGH_DIRECT), 0, 0, 0, 0, 0, 0, SCSI_IOCTL_DATA_IN, cb, 30, buf
};
union {
PUCHAR Cdb;
CDB::_CDB10* Cdb10;
CDB::_CDB16* Cdb16;
};
Cdb = s.Cdb;
if (MAXULONG < LogicalBlock || MAXUSHORT < TransferBlocks)
{
s.CdbLength = sizeof(CDB::_CDB16);
Cdb16->OperationCode = SCSIOP_READ16;
*(ULONGLONG*)Cdb16->LogicalBlock = _byteswap_uint64(LogicalBlock);
*(ULONG*)Cdb16->TransferLength = _byteswap_ulong(TransferBlocks);
}
else
{
s.CdbLength = sizeof(CDB::_CDB10);
Cdb10->OperationCode = SCSIOP_READ;
*(ULONG*)&Cdb10->LogicalBlockByte0 = _byteswap_ulong((ULONG)LogicalBlock);
*(USHORT*)&Cdb10->TransferBlocksMsb = _byteswap_ushort((USHORT)TransferBlocks);
}
DWORD ioctl_bytes;
return DeviceIoControl(fh, IOCTL_SCSI_PASS_THROUGH_DIRECT, &s, sizeof(s), &s, sizeof(s), &ioctl_bytes, NULL);
}
BOOL test_scsi_read(PCWSTR fname)
{
BOOL fOk = FALSE;
HANDLE fh = CreateFileW(fname, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (fh != INVALID_HANDLE_VALUE)
{
DWORD ioctl_bytes;
DISK_GEOMETRY_EX dg;
if (DeviceIoControl(fh, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &dg, sizeof(dg), &ioctl_bytes, 0))
{
// 16 sectors for example
ULONG cb = 16 * dg.Geometry.BytesPerSector;
if (PVOID buf = new CHAR[cb])
{
// read first 16 sectors
fOk = scsi_read(fh, buf, cb, 0, 16);
if (ULONGLONG LogicalBlock = dg.DiskSize.QuadPart / dg.Geometry.BytesPerSector)
{
// read last sector
fOk = scsi_read(fh, buf, dg.Geometry.BytesPerSector, LogicalBlock - 1, 1);
}
delete buf;
}
}
CloseHandle(fh);
}
return fOk;
}
test_scsi_read(L"\\\\?\\e:");

How to Send IOCTL's to all drivers on windows in C

Can someone provide me with a sample C code that list´s all device Names that i can open with Createfile()? i always get error code 3 : path does not exist
sample code that doesnt works:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <regstr.h>
#include <devioctl.h>
#include <usb.h>
#include <usbiodef.h>
#include <usbioctl.h>
#include <usbprint.h>
#include <setupapi.h>
#include <devguid.h>
#include <wdmguid.h>
#pragma comment(lib, "Setupapi.lib")
int main(void){
HDEVINFO deviceInfoList;
deviceInfoList = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (deviceInfoList != INVALID_HANDLE_VALUE)
{
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoList, i, &deviceInfoData); i++)
{
LPTSTR buffer = NULL;
DWORD buffersize = 0;
while (!SetupDiGetDeviceInstanceIdA(deviceInfoList, &deviceInfoData, buffer, buffersize, &buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer) delete buffer;
buffer = new TCHAR[buffersize];
}
else
{
printf("%ls\n", "error");
break;
}
}
HANDLE hFile = CreateFileA(buffer,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("InvalidHandle, error code: %d\n", GetLastError());
}
CloseHandle(hFile);
printf("%s\n", buffer);
if (buffer) { delete buffer; buffer = NULL; }
}
}
getchar();
}
my Goal is to print all valid device Names and try to get a valid handle on it that i can later user for sending ioctl`s
thx
EDIT:
ok abhineet so thats what i got now :
DWORD EnumerateDevices(){
DWORD dwResult = 0;
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);// DIGCF_ALLCLASSES
/*HDEVINFO hdev =SetupDiGetClassDevs(NULL,
0, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES); */
if (INVALID_HANDLE_VALUE != hdev) {
for (int idev = 0; idev < 100; idev++)
{
SP_DEVICE_INTERFACE_DATA did = { 0 };
did.cbSize = sizeof(did);
if (SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did))
{
DWORD cbRequired = 0;
SetupDiGetDeviceInterfaceDetail(hdev,
&did,
NULL,
0,
&cbRequired,
0);
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, cbRequired);
if (pdidd) {
pdidd->cbSize = sizeof(*pdidd);
if (SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0)) {
wprintf(L"%s\n", pdidd->DevicePath);
HANDLE hBattery = CreateFile(pdidd->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hBattery)
{
printf("Successfully opened Handle\n");
CloseHandle(hBattery);
}
else{
wprintf(L"CreateFile(%s) failed %d\n", pdidd->DevicePath, GetLastError());
}
}
else{
printf("SetupDiGetDeviceInterfaceDetail() failed %d\n", GetLastError());
}
LocalFree(pdidd);
}
}
else{
printf("SetupDiGetDeviceInterfaceDetail() failed %d\n", GetLastError());
}
}
else if (ERROR_NO_MORE_ITEMS == GetLastError())
{
printf("-NoMoreItems-");
break; // Enumeration failed - perhaps we're out of items
}
}
SetupDiDestroyDeviceInfoList(hdev);
}
else{
printf("SetupDiGetClassDevs() failed %d\n", GetLastError());
}
return dwResult;
}
i ripped the most from here : https://msdn.microsoft.com/en-us/library/windows/desktop/bb204769(v=vs.85).aspx
and my Output is :
\\?\acpi#pnp0c0a#1#{72631e54-78a4-11d0-bcf7-00aa00b7b32a}
Successfully opened Handle
-NoMoreItems-
at least i got a valid handle!
so i wanna do this an all devices avaible on the System , how to do that?
IMHO, I don't think, you can do a CreateFile on InstanceID. To do a CreateFile, you need the symbolic name of the device. You can use the following SetupAPIs,
SetupDiEnumDeviceInterfaces
SetupDiGetDeviceInterfaceDetail
The Remark section of both APIs state that,
SetupDiEnumDeviceInterfaces:: DeviceInterfaceData points to a structure that identifies a requested
device interface. To get detailed information about an interface, call
SetupDiGetDeviceInterfaceDetail. The detailed information includes the
name of the device interface that can be passed to a Win32 function
such as CreateFile (described in Microsoft Windows SDK documentation)
to get a handle to the interface.
SetupDiGetDeviceInterfaceDetail:: The interface detail returned by this function consists of a device path that can be passed to Win32
functions such as CreateFile. Do not attempt to parse the device path
symbolic name. The device path can be reused across system starts.
This might be of your use, how to get DevicePath from DeviceID

Resources