Jump to content











Photo
- - - - -

Use sys file only CreateFile


  • Please log in to reply
10 replies to this topic

#1 Muggen

Muggen
  • Members
  • 6 posts
  •  
    United Kingdom

Posted 4 weeks ago

Hi,

 

Is it possible to only use the sys file to have an ImDisk virtual disk driver in your system ?

I plan to modify the ImDisk source and the .inf file to make that possible.

 

I tried opening the driver using \\Device\\ImDisk but is not possible.

 

However, if I use the installer instead I can NtOpenFile on \\Device\\ImDiskCtl

 

But I would like to avoid having to include Ctl and have a standalone *.sys & inf file driver only. Is this possible ? 

 

I see there is a IOCTL_IMDISK_CREATE_DEVICE which I guess I can use to DeviceIoControl to create drives.


Edited by Muggen, 4 weeks ago.


#2 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13745 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 4 weeks ago

I am not sure to understand what you are asking.

Maybe these help?

http://reboot.pro/to...ly-using-scexe/

http://reboot.pro/to...rkvist/?p=13855

 

:duff:

Wonko



#3 Muggen

Muggen
  • Members
  • 6 posts
  •  
    United Kingdom

Posted 4 weeks ago

Hi,

 

Thanks for the answer.

 

The links (especially the first one) are close to what I need.

 

I want to only have a .inf and a .sys file as my ImDisk driver. Which I then want to use from a C++ Application to create a virtual disk.

 

Correct me if I am wrong but to use a driver this way I need to call CreateFile with "\\Device\\ImDiskCtl" and then use DeviceIoControl on the handle to perform actions like creating a disk etc.

 

However isnt \\Device\\ImDiskCtl pretty much the ControlPanel (cpl project in driver source) application ? Can I immediately access the .sys driver ?


Edited by Muggen, 4 weeks ago.


#4 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1344 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 4 weeks ago

\\Device\\ImDiskCtl stands for "ImDisk Control Device" and is the way you access the driver, that is, the .sys file. It is not related to the Control Panel applet in any way. You simply open \\Device\\ImDiskCtl (or \\\\?\\ImDiskCtl if you use CreateFile instead of NtOpenFile) and send IOCTL messages to it using DeviceIoControl. You don't need any other components than the .sys file for that.

 

However, the Control Panel applet imdisk.cpl (with an import library imdisk.lib) offers an API with functions you can call from your C++ application in a little bit easier way than to send IOCTL messages directly. Functions are called ImDiskCreateDevice and similar and takes parameters instead of require you to fill in data structures for the driver directly. You can look at the inc\imdisk.h source file for some description of these functions.



#5 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13745 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 4 weeks ago

I am still not sure about the actual question.

Imdisk is a driver.

There are "common" tools to install and start a driver.

A driver, once started can be interfaced with (documented in this case since it is Open Source) calls.

 

Basically you want to check what IMDISK.EXE (not necessarily the Control Panel interface) does, and replicate it in your tool, but then it would be a (no offence intended :) probably worse written copy of IMDISK.EXE) while the Registry settings detailed in one of the links might be a good way, if set before the driver start, to do simpler things with it.

 

You may also have a look at the source of the Imdisk Toolkit (by v77):

http://reboot.pro/to...imdisk-toolkit/

https://sourceforge....imdisk-toolkit/

which provides a number of features/additions to the "plain" IMDISK, that may have sources easier to read/understand. 

 

 

:duff:

Wonko



#6 Muggen

Muggen
  • Members
  • 6 posts
  •  
    United Kingdom

Posted 3 weeks ago

Both posts have helped me sort out the problem and the confusion

 

Thank you very much for the help :)


  • Olof Lagerkvist likes this

#7 Muggen

Muggen
  • Members
  • 6 posts
  •  
    United Kingdom

Posted 3 weeks ago

Hi Again,

 

I am now using CreateFile and DeviceIoControl on my C++ Application.

 

I can successfully get a handle to "\\\\?\\ImDiskCtl" and I can successfully invoke DeviceIoControl with IOCTL_IMDISK_QUERY_VERSION.

 

However when I try the same with IOCTL_IMDISK_CREATE_DEVICE it fails, with GetLastError() == 5 (which is Access Denied)

 

Any Ideas what could stop my app from creating a disk ?

 

Thanks

 

How I get access to the driver :

hDevice = CreateFileW(L"\\\\?\\ImDiskCtl",          // drive to open
0,                // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL,             // default security attributes
OPEN_EXISTING,    // disposition
NULL,                // file attributes
NULL);

The following works : 

DWORD VersionCheck;
DWORD BytesReturned;

BOOL bCheckVersion = DeviceIoControl(hDevice,
IOCTL_IMDISK_QUERY_VERSION,
NULL, 0,
&VersionCheck, sizeof VersionCheck,
&BytesReturned, NULL);

The following fails with last error 5 (even when run as adminstrator)

wchar_t wcFileName[512] = L"C:\\TestDisk.dsk";
std::size_t szStructSize = sizeof(IMDISK_CREATE_DATA) + (wcslen(wcFileName) * 2) + 2;
IMDISK_CREATE_DATA* DiskSetup = reinterpret_cast<IMDISK_CREATE_DATA*>( malloc( szStructSize ) );

memset( DiskSetup, 0, szStructSize );

if( DiskSetup )
{
DiskSetup->DeviceNumber = IMDISK_AUTO_DEVICE_NUMBER;
DiskSetup->DiskGeometry.Cylinders.QuadPart = 1024 * 1024 * 2;
DiskSetup->Flags = IMDISK_TYPE_FILE | IMDISK_DEVICE_TYPE_HD;
DiskSetup->DriveLetter = L'N';
DiskSetup->FileNameLength = wcslen( wcFileName );
wcscpy( DiskSetup->FileName, wcFileName );

DWORD dwBytesReturned = 0;
BOOL bSuccess = DeviceIoControl(hDevice, 
IOCTL_IMDISK_CREATE_DEVICE,
DiskSetup, szStructSize, 
DiskSetup, szStructSize,
&dwBytesReturned, nullptr);

if( bSuccess )
{
std::cout << "SUCCESS" << std::endl;
}
else
{
std::cout << "FAILURE" << std::endl;
}

iLastError = GetLastError();
std::cout << "Last Error : " << iLastError << std::endl;

while(true)
{
Sleep( 50 );
}
}

Edited by Muggen, 3 weeks ago.


#8 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1344 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 3 weeks ago

The file name length field is number of bytes, not characters. I think you could avoid some of the "usual" mistakes around these calls if you look at the source code for the ImDiskCreateDeviceEx API function. It is located in the cpl\drvio.c source file.

#9 Muggen

Muggen
  • Members
  • 6 posts
  •  
    United Kingdom

Posted 3 weeks ago

The file name length field is number of bytes, not characters. I think you could avoid some of the "usual" mistakes around these calls if you look at the source code for the ImDiskCreateDeviceEx API function. It is located in the cpl\drvio.c source file.

 

Thanks for the answer.

 

I had already tried DiskSetup->FileNameLength = wcslen( wcFileName ) * 2;

Unfortunately it gave me LastError = 5 



#10 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1344 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 3 weeks ago

I see now that you also pass a Win32 style path. That will not work, you need a native path. Easiest way is probably to use RtlDosPathNameToNtPathName function like I do in the API implementation.

#11 Muggen

Muggen
  • Members
  • 6 posts
  •  
    United Kingdom

Posted 3 weeks ago

Indeed the problem was solved when used RtlCreateUnicodeString and RtlDosPathNameToNtPathName_U.

 

Also I had to open the driver using GENERIC_READ | GENERIC_WRITE

hDevice = CreateFile(L"\\\\?\\ImDiskCtl",
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    NULL,
    NULL);

Thank you very much for the help :)


  • Olof Lagerkvist likes this




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users