diff --git a/.gitignore b/.gitignore
index e8eaba2..34e29ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -355,7 +355,8 @@ devio_with_options/
cab/
ImDiskNet/Help/
private/
-*/obj*
+*/objchk*
+*/objfre*
*.exe
*.dll
*.cpl
@@ -387,6 +388,9 @@ devio/devio.static.Linux_x86_64
*.diff
*.cat
*.old
+*.old2
+*.old3
+*.old4
*.err
*.zip
*.cab
@@ -400,4 +404,9 @@ changes.txt
*.gz
*.xz
*.cer
-devio/iobridge/Release64/Bridge.asm
+*/*/Release*
+*.py
+*.snk
+*.filters
+dirs.sln
+ImDiskNet/DevioNet/Server/Services/DevioDrvService.vb
diff --git a/ImDisk.sln b/ImDisk.sln
index d6f8474..b405ee9 100644
--- a/ImDisk.sln
+++ b/ImDisk.sln
@@ -22,6 +22,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution files", "Solution
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cplcore", "cplcore\cplcore.vcxproj", "{4052F81F-5D49-4457-8F78-4DCE5DAD91E1}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deviodrv", "deviodrv\deviodrv.vcxproj", "{457B6C05-3FED-4056-A4B3-B1B110242F14}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@@ -580,6 +582,102 @@ Global
{4052F81F-5D49-4457-8F78-4DCE5DAD91E1}.Win8.1 Release|Win32.Build.0 = Release|Win32
{4052F81F-5D49-4457-8F78-4DCE5DAD91E1}.Win8.1 Release|x64.ActiveCfg = Release|x64
{4052F81F-5D49-4457-8F78-4DCE5DAD91E1}.Win8.1 Release|x64.Build.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|ARM.ActiveCfg = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|ARM.Build.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|ARM.Deploy.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|ARM64.Build.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|Win32.ActiveCfg = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|Win32.Build.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|Win32.Deploy.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|x64.ActiveCfg = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|x64.Build.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Debug|x64.Deploy.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|ARM.ActiveCfg = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|ARM.Build.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|ARM.Deploy.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|ARM64.ActiveCfg = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|ARM64.Build.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|ARM64.Deploy.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|Win32.ActiveCfg = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|Win32.Build.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|Win32.Deploy.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|x64.ActiveCfg = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|x64.Build.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Release|x64.Deploy.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|ARM.ActiveCfg = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|ARM.Build.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|ARM.Deploy.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|ARM64.ActiveCfg = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|ARM64.Build.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|ARM64.Deploy.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|Win32.ActiveCfg = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|Win32.Build.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|Win32.Deploy.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|x64.ActiveCfg = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|x64.Build.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Debug|x64.Deploy.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|ARM.ActiveCfg = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|ARM.Build.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|ARM.Deploy.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|ARM64.ActiveCfg = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|ARM64.Build.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|ARM64.Deploy.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|Win32.ActiveCfg = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|Win32.Build.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|Win32.Deploy.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|x64.ActiveCfg = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|x64.Build.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win7 Release|x64.Deploy.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|ARM.ActiveCfg = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|ARM.Build.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|ARM.Deploy.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|ARM64.ActiveCfg = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|ARM64.Build.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|ARM64.Deploy.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|Win32.ActiveCfg = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|Win32.Build.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|Win32.Deploy.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|x64.ActiveCfg = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|x64.Build.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Debug|x64.Deploy.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|ARM.ActiveCfg = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|ARM.Build.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|ARM.Deploy.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|ARM64.ActiveCfg = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|ARM64.Build.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|ARM64.Deploy.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|Win32.ActiveCfg = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|Win32.Build.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|Win32.Deploy.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|x64.ActiveCfg = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|x64.Build.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8 Release|x64.Deploy.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|ARM.ActiveCfg = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|ARM.Build.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|ARM.Deploy.0 = Debug|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|ARM64.ActiveCfg = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|ARM64.Build.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|ARM64.Deploy.0 = Debug|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|Win32.ActiveCfg = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|Win32.Build.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|Win32.Deploy.0 = Debug|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|x64.ActiveCfg = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|x64.Build.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Debug|x64.Deploy.0 = Debug|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|ARM.ActiveCfg = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|ARM.Build.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|ARM.Deploy.0 = Release|ARM
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|ARM64.ActiveCfg = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|ARM64.Build.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|ARM64.Deploy.0 = Release|ARM64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|Win32.ActiveCfg = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|Win32.Build.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|Win32.Deploy.0 = Release|Win32
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|x64.ActiveCfg = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|x64.Build.0 = Release|x64
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}.Win8.1 Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ImDiskNet/DevioNet/Client/DevioProviderStream.vb b/ImDiskNet/DevioNet/Client/DevioProviderStream.vb
index 6b5f9bd..ca5199a 100644
--- a/ImDiskNet/DevioNet/Client/DevioProviderStream.vb
+++ b/ImDiskNet/DevioNet/Client/DevioProviderStream.vb
@@ -1,4 +1,6 @@
-Imports LTR.IO.ImDisk.Devio.Server.Providers
+Imports System.ComponentModel
+Imports System.IO
+Imports LTR.IO.ImDisk.Devio.Server.Providers
Namespace Client
@@ -8,8 +10,9 @@ Namespace Client
Public Class DevioProviderStream
Inherits Stream
- Private _Provider As IDevioProvider
- Private _OwnsProvider As Boolean
+ Public ReadOnly Property Provider As IDevioProvider
+
+ Public ReadOnly Property OwnsProvider As Boolean
Public Sub New(Provider As IDevioProvider, ownsProvider As Boolean)
_Provider = Provider
diff --git a/ImDiskNet/DevioNet/Client/DevioShmStream.vb b/ImDiskNet/DevioNet/Client/DevioShmStream.vb
index ff61f97..2977d84 100644
--- a/ImDiskNet/DevioNet/Client/DevioShmStream.vb
+++ b/ImDiskNet/DevioNet/Client/DevioShmStream.vb
@@ -1,4 +1,8 @@
-Imports LTR.IO.ImDisk.Devio.IMDPROXY_CONSTANTS
+Imports System.IO
+Imports System.IO.MemoryMappedFiles
+Imports System.Runtime.InteropServices
+Imports System.Threading
+Imports LTR.IO.ImDisk.Devio.IMDPROXY_CONSTANTS
Namespace Client
@@ -22,11 +26,11 @@ Namespace Client
''' communication with a Devio service using this shared memory object.
'''
''' Name of shared memory object to use for communication.
- ''' Specifies if communication should be read-only.
+ ''' Specifies if communication should be read-only.
''' Returns new instance of DevioShmStream.
- Public Shared Function Open(name As String, read_only As Boolean) As DevioShmStream
+ Public Shared Function Open(name As String, [readOnly] As Boolean) As DevioShmStream
- Return New DevioShmStream(name, read_only)
+ Return New DevioShmStream(name, [readOnly])
End Function
@@ -35,9 +39,9 @@ Namespace Client
''' communication with a Devio service using this shared memory object.
'''
''' Name of shared memory object to use for communication.
- ''' Specifies if communication should be read-only.
- Public Sub New(name As String, read_only As Boolean)
- MyBase.New(name, read_only)
+ ''' Specifies if communication should be read-only.
+ Public Sub New(name As String, [readOnly] As Boolean)
+ MyBase.New(name, [readOnly])
Try
Using Mapping = MemoryMappedFile.OpenExisting(ObjectName,
@@ -47,11 +51,11 @@ Namespace Client
End Using
- RequestEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:="Global\" & ObjectName & "_Request")
+ RequestEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:=$"Global\{ObjectName}_Request")
- ResponseEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:="Global\" & ObjectName & "_Response")
+ ResponseEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:=$"Global\{ObjectName}_Response")
- ServerMutex = New Mutex(initiallyOwned:=False, name:="Global\" & ObjectName & "_Server")
+ ServerMutex = New Mutex(initiallyOwned:=False, name:=$"Global\{ObjectName}_Server")
MapView.Write(&H0, IMDPROXY_REQ.IMDPROXY_REQ_INFO)
@@ -89,9 +93,7 @@ Namespace Client
For Each obj In New IDisposable() {ServerMutex, MapView, RequestEvent, ResponseEvent}
Try
- If obj IsNot Nothing Then
- obj.Dispose()
- End If
+ obj?.Dispose()
Catch
@@ -116,11 +118,11 @@ Namespace Client
Dim Response = MapView.Read(Of IMDPROXY_READ_RESP)(&H0)
If Response.errorno <> 0 Then
- Throw New EndOfStreamException("Read error: " & Response.errorno)
+ Throw New EndOfStreamException($"Read error: {Response.errorno}")
End If
Dim Length = CInt(Response.length)
- MapView.ReadArray(CULng(IMDPROXY_HEADER_SIZE), buffer, offset, Length)
+ MapView.ReadArray(IMDPROXY_HEADER_SIZE, buffer, offset, Length)
Position += Length
Return Length
@@ -135,7 +137,7 @@ Namespace Client
MapView.Write(&H0, Request)
- MapView.WriteArray(CULng(IMDPROXY_HEADER_SIZE), buffer, offset, count)
+ MapView.WriteArray(IMDPROXY_HEADER_SIZE, buffer, offset, count)
RequestEvent.Set()
If WaitHandle.WaitAny({ResponseEvent, ServerMutex}) <> 0 Then
@@ -144,13 +146,13 @@ Namespace Client
Dim Response = MapView.Read(Of IMDPROXY_WRITE_RESP)(&H0)
If Response.errorno <> 0 Then
- Throw New EndOfStreamException("Write error: " & Response.errorno)
+ Throw New EndOfStreamException($"Write error: {Response.errorno}")
End If
Dim Length = CInt(Response.length)
Position += Length
If Length <> count Then
- Throw New EndOfStreamException("Write length mismatch. Wrote " & Length & " of " & count & " bytes.")
+ Throw New EndOfStreamException($"Write length mismatch. Wrote {Length} of {count} bytes.")
End If
End Sub
diff --git a/ImDiskNet/DevioNet/Client/DevioStream.vb b/ImDiskNet/DevioNet/Client/DevioStream.vb
index e3b5bbb..8a7bf9d 100644
--- a/ImDiskNet/DevioNet/Client/DevioStream.vb
+++ b/ImDiskNet/DevioNet/Client/DevioStream.vb
@@ -1,158 +1,164 @@
-Namespace Client
-
- '''
- ''' Base class for classes that implement Stream for client side of ImDisk/Devio protocol.
- '''
- Public MustInherit Class DevioStream
- Inherits Stream
-
- '''
- ''' Object name used by proxy implementation.
- '''
- Public ReadOnly ObjectName As String
-
- '''
- ''' Virtual disk size of server object.
- '''
- Protected Size As Long
-
- '''
- ''' Alignment requirement for I/O at server.
- '''
- Protected Alignment As Long
-
- '''
- ''' ImDisk proxy flags specified for proxy connection.
- '''
- Protected Flags As IMDPROXY_FLAGS
-
- '''
- ''' Initiates a new instance with supplied object name and read-only flag.
- '''
- ''' Object name used by proxy implementation.
- ''' Flag set to true to indicate read-only proxy
- ''' operation.
- Protected Sub New(name As String, read_only As Boolean)
- ObjectName = name
- If read_only Then
- Flags = IMDPROXY_FLAGS.IMDPROXY_FLAG_RO
- End If
- End Sub
-
- '''
- ''' Indicates whether Stream is readable. This implementation returns a
- ''' constant value of True, because ImDisk/Devio proxy implementations are
- ''' always readable.
- '''
- Public Overrides ReadOnly Property CanRead As Boolean
- Get
- Return True
- End Get
- End Property
-
- '''
- ''' Indicates whether Stream is seekable. This implementation returns a
- ''' constant value of True.
- '''
- Public Overrides ReadOnly Property CanSeek As Boolean
- Get
- Return True
- End Get
- End Property
-
- '''
- ''' Indicates whether Stream is writable. This implementation returns True
- ''' unless ProxyFlags property contains IMDPROXY_FLAGS.IMDPROXY_FLAG_RO value.
- '''
- Public Overrides ReadOnly Property CanWrite As Boolean
- Get
- Return (Flags And IMDPROXY_FLAGS.IMDPROXY_FLAG_RO) = 0
- End Get
- End Property
-
- '''
- ''' This implementation does not do anything.
- '''
- Public Overrides Sub Flush()
-
- End Sub
-
- '''
- ''' When overriden in a derived class, closes communication and causes server side to exit.
- '''
- Public Overrides Sub Close()
- MyBase.Close()
- End Sub
-
- '''
- ''' Returns current virtual disk size.
- '''
- Public Overrides ReadOnly Property Length As Long
- Get
- Return Size
- End Get
- End Property
-
- '''
- ''' Current byte position in Stream.
- '''
- Public Overrides Property Position As Long
-
- '''
- ''' Moves current position in Stream.
- '''
- ''' Byte offset to move. Can be negative to move backwards.
- ''' Origin from where number of bytes to move counts.
- ''' Returns new absolute position in Stream.
- Public Overrides Function Seek(offset As Long, origin As SeekOrigin) As Long
-
- Select Case origin
-
- Case SeekOrigin.Begin
- Position = offset
-
- Case SeekOrigin.Current
- Position += offset
-
- Case SeekOrigin.End
- Position = Size + offset
-
- Case Else
- Throw New ArgumentException("Invalid origin", "origin")
-
- End Select
-
- Return Position
-
- End Function
-
- '''
- ''' This method is not supported in this implementation and throws a NotImplementedException.
- ''' A derived class can override this method to implement a resize feature.
- '''
- ''' New total size of Stream
- Public Overrides Sub SetLength(value As Long)
- Throw New NotImplementedException("SetLength() not implemented for DevioStream objects.")
- End Sub
-
- '''
- ''' Alignment requirement for I/O at server.
- '''
- Public ReadOnly Property RequiredAlignment As Long
- Get
- Return Alignment
- End Get
- End Property
-
- '''
- ''' ImDisk proxy flags specified for proxy connection.
- '''
- Public ReadOnly Property ProxyFlags As IMDPROXY_FLAGS
- Get
- Return Flags
- End Get
- End Property
-
- End Class
+Imports System.IO
+
+Namespace Client
+
+ '''
+ ''' Base class for classes that implement Stream for client side of ImDisk/Devio protocol.
+ '''
+ Public MustInherit Class DevioStream
+ Inherits Stream
+
+ '''
+ ''' Object name used by proxy implementation.
+ '''
+ Public ReadOnly Property ObjectName As String
+
+ '''
+ ''' Virtual disk size of server object.
+ '''
+ Protected Property Size As Long
+
+ '''
+ ''' Alignment requirement for I/O at server.
+ '''
+ Protected Property Alignment As Long
+
+ '''
+ ''' ImDisk proxy flags specified for proxy connection.
+ '''
+ Protected Property Flags As IMDPROXY_FLAGS
+
+ '''
+ ''' Initiates a new instance with supplied object name and read-only flag.
+ '''
+ ''' Object name used by proxy implementation.
+ ''' Flag set to true to indicate read-only proxy
+ ''' operation.
+ Protected Sub New(name As String, [readOnly] As Boolean)
+ If name Is Nothing Then
+ Throw New ArgumentNullException(NameOf(name))
+ End If
+
+ ObjectName = name
+ If [readOnly] Then
+ Flags = IMDPROXY_FLAGS.IMDPROXY_FLAG_RO
+ End If
+ End Sub
+
+ '''
+ ''' Indicates whether Stream is readable. This implementation returns a
+ ''' constant value of True, because ImDisk/Devio proxy implementations are
+ ''' always readable.
+ '''
+ Public Overrides ReadOnly Property CanRead As Boolean
+ Get
+ Return True
+ End Get
+ End Property
+
+ '''
+ ''' Indicates whether Stream is seekable. This implementation returns a
+ ''' constant value of True.
+ '''
+ Public Overrides ReadOnly Property CanSeek As Boolean
+ Get
+ Return True
+ End Get
+ End Property
+
+ '''
+ ''' Indicates whether Stream is writable. This implementation returns True
+ ''' unless ProxyFlags property contains IMDPROXY_FLAGS.IMDPROXY_FLAG_RO value.
+ '''
+ Public Overrides ReadOnly Property CanWrite As Boolean
+ Get
+ Return (Flags And IMDPROXY_FLAGS.IMDPROXY_FLAG_RO) = 0
+ End Get
+ End Property
+
+ '''
+ ''' This implementation does not do anything.
+ '''
+ Public Overrides Sub Flush()
+
+ End Sub
+
+ '''
+ ''' When overriden in a derived class, closes communication and causes server side to exit.
+ '''
+ Public Overrides Sub Close()
+ MyBase.Close()
+ End Sub
+
+ '''
+ ''' Returns current virtual disk size.
+ '''
+ Public Overrides ReadOnly Property Length As Long
+ Get
+ Return Size
+ End Get
+ End Property
+
+ '''
+ ''' Current byte position in Stream.
+ '''
+ Public Overrides Property Position As Long
+
+ '''
+ ''' Moves current position in Stream.
+ '''
+ ''' Byte offset to move. Can be negative to move backwards.
+ ''' Origin from where number of bytes to move counts.
+ ''' Returns new absolute position in Stream.
+ Public Overrides Function Seek(offset As Long, origin As SeekOrigin) As Long
+
+ Select Case origin
+
+ Case SeekOrigin.Begin
+ Position = offset
+
+ Case SeekOrigin.Current
+ Position += offset
+
+ Case SeekOrigin.End
+ Position = Size + offset
+
+ Case Else
+ Throw New ArgumentException("Invalid origin", NameOf(origin))
+
+ End Select
+
+ Return Position
+
+ End Function
+
+ '''
+ ''' This method is not supported in this implementation and throws a NotImplementedException.
+ ''' A derived class can override this method to implement a resize feature.
+ '''
+ ''' New total size of Stream
+ Public Overrides Sub SetLength(value As Long)
+ Throw New NotImplementedException("SetLength() not implemented for DevioStream objects.")
+ End Sub
+
+ '''
+ ''' Alignment requirement for I/O at server.
+ '''
+ Public ReadOnly Property RequiredAlignment As Long
+ Get
+ Return Alignment
+ End Get
+ End Property
+
+ '''
+ ''' ImDisk proxy flags specified for proxy connection.
+ '''
+ Public ReadOnly Property ProxyFlags As IMDPROXY_FLAGS
+ Get
+ Return Flags
+ End Get
+ End Property
+
+ End Class
End Namespace
diff --git a/ImDiskNet/DevioNet/Client/DevioTcpStream.vb b/ImDiskNet/DevioNet/Client/DevioTcpStream.vb
index 7492bef..678f063 100644
--- a/ImDiskNet/DevioNet/Client/DevioTcpStream.vb
+++ b/ImDiskNet/DevioNet/Client/DevioTcpStream.vb
@@ -1,149 +1,153 @@
-Namespace Client
+Imports System.IO
+Imports System.Net.Sockets
+Imports System.Text
- '''
- ''' Derives DevioStream and implements client side of Devio tcp/ip based communication
- ''' proxy.
- '''
- Public Class DevioTcpStream
- Inherits DevioStream
-
- Protected ReadOnly Connection As NetworkStream
-
- Protected ReadOnly Reader As BinaryReader
-
- Protected ReadOnly Writer As New BinaryWriter(New MemoryStream, Encoding.Unicode)
-
- '''
- ''' Creates a new instance by opening an tcp/ip connection to specified host and port
- ''' and starts communication with a Devio service using this connection.
- '''
- ''' Host name and port where service is listening for incoming
- ''' connection. This can be on the form hostname:port or just hostname where default
- ''' port number 9000 will be used. The hostname part can be either an IP address or a
- ''' host name.
- ''' Specifies if communication should be read-only.
- ''' Returns new instance of DevioTcpStream.
- Public Shared Function Open(name As String, read_only As Boolean) As DevioTcpStream
-
- Return New DevioTcpStream(name, read_only)
-
- End Function
+Namespace Client
'''
- ''' Creates a new instance by opening an tcp/ip connection to specified host and port
- ''' and starts communication with a Devio service using this connection.
+ ''' Derives DevioStream and implements client side of Devio tcp/ip based communication
+ ''' proxy.
'''
- ''' Host name and port where service is listening for incoming
- ''' connection. This can be on the form hostname:port or just hostname where default
- ''' port number 9000 will be used. The hostname part can be either an IP address or a
- ''' host name.
- ''' Specifies if communication should be read-only.
- Public Sub New(name As String, read_only As Boolean)
- MyBase.New(name, read_only)
-
- Try
- Dim spl = ObjectName.Split({":"}, StringSplitOptions.RemoveEmptyEntries)
- Dim server = spl(0)
- Dim port = 9000
- If spl.Length >= 2 Then
- port = Integer.Parse(spl(1))
- End If
-
- Dim Socket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
- Socket.Connect(server, port)
- Connection = New NetworkStream(Socket, ownsSocket:=True)
-
- Reader = New BinaryReader(Connection, Encoding.Unicode)
-
- Writer.Write(IMDPROXY_REQ.IMDPROXY_REQ_INFO)
- Writer.Flush()
- With DirectCast(Writer.BaseStream, MemoryStream)
- .WriteTo(Connection)
- .SetLength(0)
- .Position = 0
- End With
- Connection.Flush()
-
- Size = Reader.ReadInt64()
- Alignment = Reader.ReadInt64()
- Flags = Flags Or CType(Reader.ReadInt64(), IMDPROXY_FLAGS)
-
- Catch
- Dispose()
- Throw
-
- End Try
-
- End Sub
-
- Public Overrides Sub Close()
- MyBase.Close()
-
- For Each obj In New IDisposable() {Writer, Reader, Connection}
- Try
- If obj IsNot Nothing Then
- obj.Dispose()
- End If
-
- Catch
-
- End Try
- Next
- End Sub
-
- Public Overrides Function Read(buffer As Byte(), offset As Integer, count As Integer) As Integer
-
- Writer.Write(IMDPROXY_REQ.IMDPROXY_REQ_READ)
- Writer.Write(Position)
- Writer.Write(CLng(count))
- Writer.Flush()
- With DirectCast(Writer.BaseStream, MemoryStream)
- .WriteTo(Connection)
- .SetLength(0)
- .Position = 0
- End With
- Connection.Flush()
-
- Dim ErrorCode = Reader.ReadUInt64()
- If ErrorCode <> 0 Then
- Throw New EndOfStreamException("Read error: " & ErrorCode)
- End If
- Dim Length = CInt(Reader.ReadInt64())
-
- Length = Reader.Read(buffer, offset, Length)
- Position += Length
-
- Return Length
-
- End Function
-
- Public Overrides Sub Write(buffer As Byte(), offset As Integer, count As Integer)
-
- Writer.Write(IMDPROXY_REQ.IMDPROXY_REQ_WRITE)
- Writer.Write(Position)
- Writer.Write(CLng(count))
- Writer.Write(buffer, offset, count)
- Writer.Flush()
- With DirectCast(Writer.BaseStream, MemoryStream)
- .WriteTo(Connection)
- .SetLength(0)
- .Position = 0
- End With
- Connection.Flush()
-
- Dim ErrorCode = Reader.ReadUInt64()
- If ErrorCode <> 0 Then
- Throw New EndOfStreamException("Write error: " & ErrorCode)
- End If
- Dim Length = Reader.ReadInt64()
- Position += Length
-
- If Length <> count Then
- Throw New EndOfStreamException("Write length mismatch. Wrote " & Length & " of " & count & " bytes.")
- End If
-
- End Sub
-
- End Class
+ Public Class DevioTcpStream
+ Inherits DevioStream
+
+ Protected ReadOnly Property Connection As NetworkStream
+
+ Protected ReadOnly Property Reader As BinaryReader
+
+ Protected ReadOnly Property Writer As New BinaryWriter(New MemoryStream, Encoding.Unicode)
+
+ '''
+ ''' Creates a new instance by opening an tcp/ip connection to specified host and port
+ ''' and starts communication with a Devio service using this connection.
+ '''
+ ''' Host name and port where service is listening for incoming
+ ''' connection. This can be on the form hostname:port or just hostname where default
+ ''' port number 9000 will be used. The hostname part can be either an IP address or a
+ ''' host name.
+ ''' Specifies if communication should be read-only.
+ ''' Returns new instance of DevioTcpStream.
+ Public Shared Function Open(name As String, [readOnly] As Boolean) As DevioTcpStream
+
+ Return New DevioTcpStream(name, [readOnly])
+
+ End Function
+
+ '''
+ ''' Creates a new instance by opening an tcp/ip connection to specified host and port
+ ''' and starts communication with a Devio service using this connection.
+ '''
+ ''' Host name and port where service is listening for incoming
+ ''' connection. This can be on the form hostname:port or just hostname where default
+ ''' port number 9000 will be used. The hostname part can be either an IP address or a
+ ''' host name.
+ ''' Specifies if communication should be read-only.
+ Public Sub New(name As String, [readOnly] As Boolean)
+ MyBase.New(name, [readOnly])
+
+ Try
+ Dim spl = ObjectName.Split({":"}, StringSplitOptions.RemoveEmptyEntries)
+ Dim server = spl(0)
+ Dim port = 9000
+ If spl.Length >= 2 Then
+ port = Integer.Parse(spl(1), Globalization.NumberFormatInfo.InvariantInfo)
+ End If
+
+ Dim Socket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
+ Socket.Connect(server, port)
+ Connection = New NetworkStream(Socket, ownsSocket:=True)
+
+ Reader = New BinaryReader(Connection, Encoding.Unicode)
+
+ Writer.Write(IMDPROXY_REQ.IMDPROXY_REQ_INFO)
+ Writer.Flush()
+ With DirectCast(Writer.BaseStream, MemoryStream)
+ .WriteTo(Connection)
+ .SetLength(0)
+ .Position = 0
+ End With
+ Connection.Flush()
+
+ Size = Reader.ReadInt64()
+ Alignment = Reader.ReadInt64()
+ Flags = Flags Or CType(Reader.ReadInt64(), IMDPROXY_FLAGS)
+
+ Catch
+ Dispose()
+ Throw
+
+ End Try
+
+ End Sub
+
+ Public Overrides Sub Close()
+ MyBase.Close()
+
+ For Each obj In New IDisposable() {Writer, Reader, Connection}
+ Try
+ If obj IsNot Nothing Then
+ obj.Dispose()
+ End If
+
+ Catch
+
+ End Try
+ Next
+ End Sub
+
+ Public Overrides Function Read(buffer As Byte(), offset As Integer, count As Integer) As Integer
+
+ Writer.Write(IMDPROXY_REQ.IMDPROXY_REQ_READ)
+ Writer.Write(Position)
+ Writer.Write(CLng(count))
+ Writer.Flush()
+ With DirectCast(Writer.BaseStream, MemoryStream)
+ .WriteTo(Connection)
+ .SetLength(0)
+ .Position = 0
+ End With
+ Connection.Flush()
+
+ Dim ErrorCode = Reader.ReadUInt64()
+ If ErrorCode <> 0 Then
+ Throw New EndOfStreamException("Read error: " & ErrorCode)
+ End If
+ Dim Length = CInt(Reader.ReadInt64())
+
+ Length = Reader.Read(buffer, offset, Length)
+ Position += Length
+
+ Return Length
+
+ End Function
+
+ Public Overrides Sub Write(buffer As Byte(), offset As Integer, count As Integer)
+
+ Writer.Write(IMDPROXY_REQ.IMDPROXY_REQ_WRITE)
+ Writer.Write(Position)
+ Writer.Write(CLng(count))
+ Writer.Write(buffer, offset, count)
+ Writer.Flush()
+ With DirectCast(Writer.BaseStream, MemoryStream)
+ .WriteTo(Connection)
+ .SetLength(0)
+ .Position = 0
+ End With
+ Connection.Flush()
+
+ Dim ErrorCode = Reader.ReadUInt64()
+ If ErrorCode <> 0 Then
+ Throw New EndOfStreamException("Write error: " & ErrorCode)
+ End If
+ Dim Length = Reader.ReadInt64()
+ Position += Length
+
+ If Length <> count Then
+ Throw New EndOfStreamException("Write length mismatch. Wrote " & Length & " of " & count & " bytes.")
+ End If
+
+ End Sub
+
+ End Class
End Namespace
diff --git a/ImDiskNet/DevioNet/DevioNet.vbproj b/ImDiskNet/DevioNet/DevioNet.vbproj
index c4d2ee8..c2b467b 100644
--- a/ImDiskNet/DevioNet/DevioNet.vbproj
+++ b/ImDiskNet/DevioNet/DevioNet.vbproj
@@ -1,167 +1,26 @@

-
+
+
+
- Debug
- x86
-
-
-
-
- {C8131F7E-E240-4A1B-8D3D-FC4E5DBED050}
- Library
-
-
+
LTR.IO.ImDisk.Devio
- DevioNet
- 512
- Windows
- v4.0
-
-
-
-
- x86
- true
- full
- true
- true
- bin\Debug\
- DevioNet.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
-
-
- x86
- pdbonly
- false
- true
- true
- bin\Release\
- DevioNet.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
-
-
- On
-
-
- Binary
-
-
- On
-
-
- On
-
-
- true
- true
- true
- ..\Debug\
- DevioNet.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
- full
- AnyCPU
- true
- true
-
-
- true
- ..\Release\
- DevioNet.xml
- true
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
- pdbonly
- AnyCPU
-
-
- true
-
-
+ DevioNet
+ ImDisk Devio for DiscUtils Library
+
DevioNet.snk
+ false
+
+ net40;netstandard2.0
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- Application.myapp
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
-
-
-
-
-
-
- VbMyResourcesResXFileCodeGenerator
- Resources.Designer.vb
- My.Resources
- Designer
-
-
-
-
-
-
- MyApplicationCodeGenerator
- Application.Designer.vb
-
-
- SettingsSingleFileGenerator
- My
- Settings.Designer.vb
-
+
+
-
- {3efcb6f8-ef7e-4f60-a0de-bb197240fcc9}
- ImDiskNet
-
+
-
-
-
\ No newline at end of file
+
+
diff --git a/ImDiskNet/DevioNet/Enums.vb b/ImDiskNet/DevioNet/Enums.vb
index 17d0973..e21ef16 100644
--- a/ImDiskNet/DevioNet/Enums.vb
+++ b/ImDiskNet/DevioNet/Enums.vb
@@ -1,4 +1,9 @@
-Public Enum IMDPROXY_REQ As ULong
+#Disable Warning CA1707 ' Identifiers should not contain underscores
+#Disable Warning IDE1006 ' Naming Styles
+
+Imports System.Runtime.InteropServices
+
+Public Enum IMDPROXY_REQ As ULong
'''
''' No operation.
@@ -45,6 +50,7 @@
IMDPROXY_REQ_ZERO
End Enum
+
Public Enum IMDPROXY_FLAGS As ULong
IMDPROXY_FLAG_NONE = 0UL
IMDPROXY_FLAG_RO = 1UL
@@ -72,15 +78,15 @@ End Class
Public Structure IMDPROXY_CONNECT_REQ
- Public request_code As IMDPROXY_REQ
- Public flags As ULong
- Public length As ULong
+ Public Property request_code As IMDPROXY_REQ
+ Public Property flags As ULong
+ Public Property length As ULong
End Structure
Public Structure IMDPROXY_CONNECT_RESP
- Public error_code As ULong
- Public object_ptr As ULong
+ Public Property error_code As ULong
+ Public Property object_ptr As ULong
End Structure
'''
@@ -94,42 +100,42 @@ Public Structure IMDPROXY_INFO_RESP
'''
''' Total size in bytes of virtual image
'''
- Public file_size As ULong
+ Public Property file_size As ULong
'''
''' Required alignment in bytes for I/O requests sent to this proxy service
'''
- Public req_alignment As ULong
+ Public Property req_alignment As ULong
'''
''' Flags from IMDPROXY_FLAGS enumeration
'''
- Public flags As IMDPROXY_FLAGS
+ Public Property flags As IMDPROXY_FLAGS
End Structure
Public Structure IMDPROXY_READ_REQ
- Public request_code As IMDPROXY_REQ
- Public offset As ULong
- Public length As ULong
+ Public Property request_code As IMDPROXY_REQ
+ Public Property offset As ULong
+ Public Property length As ULong
End Structure
Public Structure IMDPROXY_READ_RESP
- Public errorno As ULong
- Public length As ULong
+ Public Property errorno As ULong
+ Public Property length As ULong
End Structure
Public Structure IMDPROXY_WRITE_REQ
- Public request_code As IMDPROXY_REQ
- Public offset As ULong
- Public length As ULong
+ Public Property request_code As IMDPROXY_REQ
+ Public Property offset As ULong
+ Public Property length As ULong
End Structure
Public Structure IMDPROXY_WRITE_RESP
- Public errorno As ULong
- Public length As ULong
+ Public Property errorno As ULong
+ Public Property length As ULong
End Structure
diff --git a/ImDiskNet/DevioNet/GlobalSuppressions.vb b/ImDiskNet/DevioNet/GlobalSuppressions.vb
new file mode 100644
index 0000000..fafdca9
--- /dev/null
+++ b/ImDiskNet/DevioNet/GlobalSuppressions.vb
@@ -0,0 +1,9 @@
+' This file is used by Code Analysis to maintain SuppressMessage
+' attributes that are applied to this project.
+' Project-level suppressions either have no target or are given
+' a specific target and scoped to a namespace, type, member, etc.
+
+Imports System.Diagnostics.CodeAnalysis
+
+
+
diff --git a/ImDiskNet/DevioNet/My Project/AssemblyInfo.vb b/ImDiskNet/DevioNet/My Project/AssemblyInfo.vb
index 2cf7e41..14cdedd 100644
--- a/ImDiskNet/DevioNet/My Project/AssemblyInfo.vb
+++ b/ImDiskNet/DevioNet/My Project/AssemblyInfo.vb
@@ -8,28 +8,7 @@ Imports System.Runtime.InteropServices
' Review the values of the assembly attributes
-
-
-
-
-
-
-
'The following GUID is for the ID of the typelib if this project is exposed to COM
-
-
-' Version information for an assembly consists of the following four values:
-'
-' Major Version
-' Minor Version
-' Build Number
-' Revision
-'
-' You can specify all the values or you can default the Build and Revision Numbers
-' by using the '*' as shown below:
-'
-
-
-
+
diff --git a/ImDiskNet/DevioNet/My Project/Settings.Designer.vb b/ImDiskNet/DevioNet/My Project/Settings.Designer.vb
deleted file mode 100644
index 46e203d..0000000
--- a/ImDiskNet/DevioNet/My Project/Settings.Designer.vb
+++ /dev/null
@@ -1,73 +0,0 @@
-'------------------------------------------------------------------------------
-'
-' This code was generated by a tool.
-' Runtime Version:4.0.30319.239
-'
-' Changes to this file may cause incorrect behavior and will be lost if
-' the code is regenerated.
-'
-'------------------------------------------------------------------------------
-
-Option Strict On
-Option Explicit On
-
-
-Namespace My
-
-
- Partial Friend NotInheritable Class MySettings
- Inherits Global.System.Configuration.ApplicationSettingsBase
-
- Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()), MySettings)
-
-#Region "My.Settings Auto-Save Functionality"
-#If _MyType = "WindowsForms" Then
- Private Shared addedHandler As Boolean
-
- Private Shared addedHandlerLockObject As New Object
-
-
- Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
- If My.Application.SaveMySettingsOnExit Then
- My.Settings.Save()
- End If
- End Sub
-#End If
-#End Region
-
- Public Shared ReadOnly Property [Default]() As MySettings
- Get
-
-#If _MyType = "WindowsForms" Then
- If Not addedHandler Then
- SyncLock addedHandlerLockObject
- If Not addedHandler Then
- AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
- addedHandler = True
- End If
- End SyncLock
- End If
-#End If
- Return defaultInstance
- End Get
- End Property
- End Class
-End Namespace
-
-Namespace My
-
-
- Friend Module MySettingsProperty
-
-
- Friend ReadOnly Property Settings() As Global.LTR.IO.ImDisk.Devio.My.MySettings
- Get
- Return Global.LTR.IO.ImDisk.Devio.My.MySettings.Default
- End Get
- End Property
- End Module
-End Namespace
diff --git a/ImDiskNet/DevioNet/Server/Providers/DevioProviderFromStream.vb b/ImDiskNet/DevioNet/Server/Providers/DevioProviderFromStream.vb
index 0a44d01..706c68b 100644
--- a/ImDiskNet/DevioNet/Server/Providers/DevioProviderFromStream.vb
+++ b/ImDiskNet/DevioNet/Server/Providers/DevioProviderFromStream.vb
@@ -1,4 +1,6 @@
-Namespace Server.Providers
+Imports System.IO
+
+Namespace Server.Providers
'''
''' Class that implements IDevioProvider interface with a System.IO.Stream
@@ -23,7 +25,7 @@
''' to an object of a class derived from System.IO.Stream.
'''
''' Object of a class derived from System.IO.Stream.
- ''' Indicates whether Stream object will be automacially closed when this
+ ''' Indicates whether Stream object will be automatically closed when this
''' instance is disposed.
Public Sub New(Stream As Stream, ownsStream As Boolean)
_BaseStream = Stream
diff --git a/ImDiskNet/DevioNet/Server/Providers/DevioProviderManagedBase.vb b/ImDiskNet/DevioNet/Server/Providers/DevioProviderManagedBase.vb
index 46721ed..42227f8 100644
--- a/ImDiskNet/DevioNet/Server/Providers/DevioProviderManagedBase.vb
+++ b/ImDiskNet/DevioNet/Server/Providers/DevioProviderManagedBase.vb
@@ -1,4 +1,6 @@
-Namespace Server.Providers
+Imports System.Runtime.InteropServices
+
+Namespace Server.Providers
'''
''' Base class for implementing IDevioProvider interface with a storage backend where
diff --git a/ImDiskNet/DevioNet/Server/Providers/DevioProviderUnmanagedBase.vb b/ImDiskNet/DevioNet/Server/Providers/DevioProviderUnmanagedBase.vb
index 3fa7b62..cbae279 100644
--- a/ImDiskNet/DevioNet/Server/Providers/DevioProviderUnmanagedBase.vb
+++ b/ImDiskNet/DevioNet/Server/Providers/DevioProviderUnmanagedBase.vb
@@ -1,4 +1,6 @@
-Namespace Server.Providers
+Imports System.Runtime.InteropServices
+
+Namespace Server.Providers
'''
''' Base class for implementing IDevioProvider interface with a storage backend where
@@ -33,7 +35,7 @@
Private Function Read(buffer As Byte(), bufferoffset As Integer, count As Integer, fileoffset As Long) As Integer Implements IDevioProvider.Read
If buffer Is Nothing Then
- Throw New ArgumentNullException("buffer")
+ Throw New ArgumentNullException(NameOf(buffer))
ElseIf bufferoffset + count > buffer.Length Then
Throw New ArgumentException("buffer too small")
End If
@@ -62,7 +64,7 @@
Private Function Write(buffer As Byte(), bufferoffset As Integer, count As Integer, fileoffset As Long) As Integer Implements IDevioProvider.Write
If buffer Is Nothing Then
- Throw New ArgumentNullException("buffer")
+ Throw New ArgumentNullException(NameOf(buffer))
ElseIf bufferoffset + count > buffer.Length Then
Throw New ArgumentException("buffer too small")
End If
diff --git a/ImDiskNet/DevioNet/Server/Services/DevioNoneService.vb b/ImDiskNet/DevioNet/Server/Services/DevioNoneService.vb
index c27414f..aebdd2d 100644
--- a/ImDiskNet/DevioNet/Server/Services/DevioNoneService.vb
+++ b/ImDiskNet/DevioNet/Server/Services/DevioNoneService.vb
@@ -1,4 +1,6 @@
-Imports LTR.IO.ImDisk.Devio.Server.Providers
+Imports System.Collections.ObjectModel
+Imports System.IO
+Imports LTR.IO.ImDisk.Devio.Server.Providers
Namespace Server.Services
@@ -13,7 +15,7 @@ Namespace Server.Services
'''
''' Name and path of image file mounted by ImDisk Virtual Disk Driver.
'''
- Public ReadOnly Imagefile As String
+ Public ReadOnly Property Imagefile As String
Private ReadOnly _Access As FileAccess
@@ -29,7 +31,7 @@ Namespace Server.Services
_Access = Access
Offset = ImDiskAPI.GetOffsetByFileExt(Imagefile)
- Me.Imagefile = Imagefile
+ Me._Imagefile = Imagefile
End Sub
@@ -38,13 +40,13 @@ Namespace Server.Services
''' structure objects.
'''
''' Collection of PARTITION_INFORMATION structures objects.
- Public Overrides Function GetPartitionInformation() As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
- Return ImDiskAPI.GetPartitionInformation(Imagefile, SectorSize, Offset)
+ Public Overrides Function GetPartitionInformation() As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
+ Return ImDiskAPI.GetPartitionInformation(_Imagefile, SectorSize, Offset)
End Function
Protected Overrides ReadOnly Property ImDiskProxyObjectName As String
Get
- Return Imagefile
+ Return _Imagefile
End Get
End Property
diff --git a/ImDiskNet/DevioNet/Server/Services/DevioServiceBase.vb b/ImDiskNet/DevioNet/Server/Services/DevioServiceBase.vb
index 3eec322..81ff0fd 100644
--- a/ImDiskNet/DevioNet/Server/Services/DevioServiceBase.vb
+++ b/ImDiskNet/DevioNet/Server/Services/DevioServiceBase.vb
@@ -1,4 +1,7 @@
-Imports LTR.IO.ImDisk.Devio.Server.Providers
+Imports System.Collections.ObjectModel
+Imports System.ComponentModel
+Imports System.Threading
+Imports LTR.IO.ImDisk.Devio.Server.Providers
Namespace Server.Services
@@ -28,7 +31,7 @@ Namespace Server.Services
''' Indicates whether DevioProvider will be automatically closed when this instance
''' is disposed.
'''
- Public ReadOnly OwnsProvider As Boolean
+ Public ReadOnly Property OwnsProvider As Boolean
'''
''' Size of virtual disk device.
@@ -127,6 +130,10 @@ Namespace Server.Services
''' instance is disposed.
Protected Sub New(DevioProvider As IDevioProvider, OwnsProvider As Boolean)
+ If DevioProvider Is Nothing Then
+ Throw New ArgumentNullException(NameOf(DevioProvider))
+ End If
+
Me.OwnsProvider = OwnsProvider
_DevioProvider = DevioProvider
@@ -141,7 +148,7 @@ Namespace Server.Services
''' Creates a device reader delegate used to directly read from device through this instance.
'''
''' A delegate that can be used to directly read from device through this instance.
- Protected Overridable Function GetDeviceReader() As DLL.ImDiskReadFileUnmanagedProc
+ Protected Overridable Function GetDeviceReader() As UnsafeNativeMethods.ImDiskReadFileUnmanagedProc
Return _
Function(handle As IntPtr,
@@ -168,7 +175,7 @@ Namespace Server.Services
''' structure objects.
'''
''' Collection of PARTITION_INFORMATION structures objects.
- Public Overridable Function GetPartitionInformation() As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Overridable Function GetPartitionInformation() As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
Return ImDiskAPI.GetPartitionInformation(Nothing, GetDeviceReader(), SectorSize, Offset)
@@ -311,15 +318,15 @@ Namespace Server.Services
Exit Do
Catch ex As Win32Exception When (
- ex.NativeErrorCode = NativeFileIO.Win32API.ERROR_DEVICE_REMOVED OrElse
- ex.NativeErrorCode = NativeFileIO.Win32API.ERROR_DEV_NOT_EXIST)
+ ex.NativeErrorCode = NativeFileIO.UnsafeNativeMethods.ERROR_DEVICE_REMOVED OrElse
+ ex.NativeErrorCode = NativeFileIO.UnsafeNativeMethods.ERROR_DEV_NOT_EXIST)
_ImDiskDeviceNumber = UInteger.MaxValue
Exit Do
Catch ex As Win32Exception When (
i < 40 AndAlso
- ex.NativeErrorCode = NativeFileIO.Win32API.ERROR_ACCESS_DENIED)
+ ex.NativeErrorCode = NativeFileIO.UnsafeNativeMethods.ERROR_ACCESS_DENIED)
i += 1
Thread.Sleep(100)
@@ -378,7 +385,7 @@ Namespace Server.Services
Public Overridable ReadOnly Property ImDiskDeviceNumber As UInteger
Get
If _ImDiskDeviceNumber = UInteger.MaxValue Then
- Throw New IOException("No ImDisk Virtual Disk Device currently associated with this instance.")
+ Throw New InvalidOperationException("No ImDisk Virtual Disk Device currently associated with this instance.")
End If
Return _ImDiskDeviceNumber
End Get
diff --git a/ImDiskNet/DevioNet/Server/Services/DevioShmService.vb b/ImDiskNet/DevioNet/Server/Services/DevioShmService.vb
index c7d994d..3108e44 100644
--- a/ImDiskNet/DevioNet/Server/Services/DevioShmService.vb
+++ b/ImDiskNet/DevioNet/Server/Services/DevioShmService.vb
@@ -1,5 +1,10 @@
-Imports LTR.IO.ImDisk.Devio.IMDPROXY_CONSTANTS
+Imports System.IO
+Imports System.IO.MemoryMappedFiles
+Imports System.Runtime.InteropServices
+Imports System.Threading
+Imports LTR.IO.ImDisk.Devio.IMDPROXY_CONSTANTS
Imports LTR.IO.ImDisk.Devio.Server.Providers
+Imports Microsoft.Win32.SafeHandles
Namespace Server.Services
@@ -35,11 +40,10 @@ Namespace Server.Services
End Get
End Property
- Private Shared _random As New Random
Private Shared Function GetNextRandomValue() As Integer
- SyncLock _random
- Return _random.Next()
- End SyncLock
+ Dim value As Integer
+ NativeFileIO.UnsafeNativeMethods.RtlGenRandom(value, 4)
+ Return value
End Function
'''
@@ -91,7 +95,7 @@ Namespace Server.Services
''' instance is disposed.
''' Buffer size to use for shared memory I/O communication.
Public Sub New(DevioProvider As IDevioProvider, OwnsProvider As Boolean, BufferSize As Long)
- MyClass.New("devio-" & GetNextRandomValue(), DevioProvider, OwnsProvider, BufferSize)
+ MyClass.New($"devio-{GetNextRandomValue()}", DevioProvider, OwnsProvider, BufferSize)
End Sub
'''
@@ -115,15 +119,15 @@ Namespace Server.Services
Dim ServerMutex As Mutex
Try
- Trace.WriteLine("Creating objects for shared memory communication '" & _ObjectName & "'.")
+ Trace.WriteLine($"Creating objects for shared memory communication '{_ObjectName}'.")
- RequestEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:="Global\" & _ObjectName & "_Request")
+ RequestEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:=$"Global\{_ObjectName}_Request")
DisposableObjects.Add(RequestEvent)
- ResponseEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:="Global\" & _ObjectName & "_Response")
+ ResponseEvent = New EventWaitHandle(initialState:=False, mode:=EventResetMode.AutoReset, name:=$"Global\{_ObjectName}_Response")
DisposableObjects.Add(ResponseEvent)
- ServerMutex = New Mutex(initiallyOwned:=False, name:="Global\" & _ObjectName & "_Server")
+ ServerMutex = New Mutex(initiallyOwned:=False, name:=$"Global\{_ObjectName}_Server")
DisposableObjects.Add(ServerMutex)
If ServerMutex.WaitOne(0) = False Then
@@ -132,12 +136,21 @@ Namespace Server.Services
Return
End If
- Mapping = MemoryMappedFile.CreateNew("Global\" & _ObjectName,
+#If NETFRAMEWORK AndAlso Not NET46_OR_GREATER Then
+ Mapping = MemoryMappedFile.CreateNew($"Global\{_ObjectName}",
_BufferSize,
MemoryMappedFileAccess.ReadWrite,
MemoryMappedFileOptions.None,
Nothing,
HandleInheritability.None)
+#Else
+ Mapping = MemoryMappedFile.CreateNew($"Global\{_ObjectName}",
+ _BufferSize,
+ MemoryMappedFileAccess.ReadWrite,
+ MemoryMappedFileOptions.None,
+ HandleInheritability.None)
+#End If
+
DisposableObjects.Add(Mapping)
Dim MapAccessor = Mapping.CreateViewAccessor()
@@ -146,7 +159,7 @@ Namespace Server.Services
MapView = MapAccessor.SafeMemoryMappedViewHandle
DisposableObjects.Add(MapView)
- Trace.WriteLine("Created shared memory object, " & MapView.ByteLength & " bytes.")
+ Trace.WriteLine($"Created shared memory object, {MapView.ByteLength} bytes.")
Trace.WriteLine("Raising service ready event.")
OnServiceReady()
@@ -204,7 +217,7 @@ Namespace Server.Services
Return
Case Else
- Trace.WriteLine("Unsupported request code: " & RequestCode.ToString())
+ Trace.WriteLine($"Unsupported request code: {RequestCode}")
Return
End Select
@@ -222,7 +235,7 @@ Namespace Server.Services
Trace.WriteLine("Client disconnected.")
Catch ex As Exception
- Trace.WriteLine("Unhandled exception in service thread: " & ex.ToString())
+ Trace.WriteLine($"Unhandled exception in service thread: {ex}")
OnServiceUnhandledException(New UnhandledExceptionEventArgs(ex, True))
Finally
@@ -262,15 +275,15 @@ Namespace Server.Services
Try
If ReadLength > MapView.ByteLength - IMDPROXY_HEADER_SIZE Then
- Trace.WriteLine("Requested read length " & ReadLength & ", lowered to " & CInt(MapView.ByteLength - CInt(IMDPROXY_HEADER_SIZE)) & " bytes.")
- ReadLength = CInt(MapView.ByteLength - CInt(IMDPROXY_HEADER_SIZE))
+ Trace.WriteLine($"Requested read length {ReadLength}, lowered to {MapView.ByteLength - IMDPROXY_HEADER_SIZE} bytes.")
+ ReadLength = CInt(MapView.ByteLength - IMDPROXY_HEADER_SIZE)
End If
Response.length = CULng(DevioProvider.Read(MapView.DangerousGetHandle(), IMDPROXY_HEADER_SIZE, ReadLength, Offset))
Response.errorno = 0
Catch ex As Exception
Trace.WriteLine(ex.ToString())
- Trace.WriteLine("Read request at " & Offset.ToString("X").PadLeft(8, "0"c) & " for " & ReadLength & " bytes.")
+ Trace.WriteLine($"Read request at 0x{Offset:X8} for {ReadLength} bytes.")
Response.errorno = 1
Response.length = 0
@@ -297,7 +310,7 @@ Namespace Server.Services
Try
If Length > MapView.ByteLength - IMDPROXY_HEADER_SIZE Then
- Throw New Exception("Requested write length " & Length & ". Buffer size is " & CInt(MapView.ByteLength - CInt(IMDPROXY_HEADER_SIZE)) & " bytes.")
+ Throw New Exception($"Requested write length {Length}. Buffer size is {CInt(MapView.ByteLength - IMDPROXY_HEADER_SIZE)} bytes.")
End If
Length = DevioProvider.Write(MapView.DangerousGetHandle(), IMDPROXY_HEADER_SIZE, Length, Offset)
Response.errorno = 0
@@ -305,7 +318,7 @@ Namespace Server.Services
Catch ex As Exception
Trace.WriteLine(ex.ToString())
- Trace.WriteLine("Write request at " & Offset.ToString("X").PadLeft(8, "0"c) & " for " & Length & " bytes.")
+ Trace.WriteLine($"Write request at 0x{Offset:X8} for {Length} bytes.")
Response.errorno = 1
Response.length = 0
@@ -327,49 +340,6 @@ Namespace Server.Services
End Get
End Property
- '''
- ''' A System.Collections.Generic.List(Of T) extended with IDisposable implementation that disposes each
- ''' object in the list when the list is disposed.
- '''
- '''
-
- Private Class DisposableList(Of T As IDisposable)
- Inherits List(Of T)
-
- Implements IDisposable
-
- Private disposedValue As Boolean ' To detect redundant calls
-
- ' IDisposable
- Protected Overridable Sub Dispose(disposing As Boolean)
- If Not Me.disposedValue Then
- If disposing Then
- ' TODO: free managed resources when explicitly called
- For Each obj In Me
- obj.Dispose()
- Next
- End If
- End If
- Me.disposedValue = True
-
- ' TODO: free shared unmanaged resources
- Clear()
-
- End Sub
-
- ' This code added by Visual Basic to correctly implement the disposable pattern.
- Public Sub Dispose() Implements IDisposable.Dispose
- ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
- Dispose(True)
- GC.SuppressFinalize(Me)
- End Sub
-
- Protected Overrides Sub Finalize()
- Dispose(False)
- MyBase.Finalize()
- End Sub
- End Class
-
End Class
End Namespace
diff --git a/ImDiskNet/DevioNet/Server/Services/DevioTcpService.vb b/ImDiskNet/DevioNet/Server/Services/DevioTcpService.vb
index 1099f37..e8e25f7 100644
--- a/ImDiskNet/DevioNet/Server/Services/DevioTcpService.vb
+++ b/ImDiskNet/DevioNet/Server/Services/DevioTcpService.vb
@@ -1,234 +1,238 @@
-Imports LTR.IO.ImDisk.Devio.IMDPROXY_CONSTANTS
+Imports System.IO
+Imports System.Net
+Imports System.Net.Sockets
+Imports System.Text
+Imports LTR.IO.ImDisk.Devio.IMDPROXY_CONSTANTS
Imports LTR.IO.ImDisk.Devio.Server.Providers
Namespace Server.Services
- '''
- ''' Class that implements server end of ImDisk/Devio TCP/IP based communication protocol.
- ''' It uses an object implementing IDevioProvider interface as storage backend
- ''' for I/O requests received from client.
- '''
- Public Class DevioTcpService
- Inherits DevioServiceBase
-
'''
- ''' Server endpoint where this service listens for client connection.
+ ''' Class that implements server end of ImDisk/Devio TCP/IP based communication protocol.
+ ''' It uses an object implementing IDevioProvider interface as storage backend
+ ''' for I/O requests received from client.
'''
- Public ReadOnly ListenEndPoint As IPEndPoint
+ Public Class DevioTcpService
+ Inherits DevioServiceBase
- '''
- ''' Creates a new service instance with enough data to later run a service that acts as server end in ImDisk/Devio
- ''' TCP/IP based communication.
- '''
- ''' IP address where service should listen for client connection.
- ''' IP port where service should listen for client connection.
- ''' IDevioProvider object to that serves as storage backend for this service.
- ''' Indicates whether DevioProvider object will be automatically closed when this
- ''' instance is disposed.
- Public Sub New(ListenAddress As IPAddress, ListenPort As Integer, DevioProvider As IDevioProvider, OwnsProvider As Boolean)
- MyBase.New(DevioProvider, OwnsProvider)
+ '''
+ ''' Server endpoint where this service listens for client connection.
+ '''
+ Public ReadOnly Property ListenEndPoint As IPEndPoint
- ListenEndPoint = New IPEndPoint(ListenAddress, ListenPort)
+ '''
+ ''' Creates a new service instance with enough data to later run a service that acts as server end in ImDisk/Devio
+ ''' TCP/IP based communication.
+ '''
+ ''' IP address where service should listen for client connection.
+ ''' IP port where service should listen for client connection.
+ ''' IDevioProvider object to that serves as storage backend for this service.
+ ''' Indicates whether DevioProvider object will be automatically closed when this
+ ''' instance is disposed.
+ Public Sub New(ListenAddress As IPAddress, ListenPort As Integer, DevioProvider As IDevioProvider, OwnsProvider As Boolean)
+ MyBase.New(DevioProvider, OwnsProvider)
- End Sub
+ ListenEndPoint = New IPEndPoint(ListenAddress, ListenPort)
- '''
- ''' Creates a new service instance with enough data to later run a service that acts as server end in ImDisk/Devio
- ''' TCP/IP based communication.
- '''
- ''' IP port where service should listen for client connection. Instance will listen on all
- ''' interfaces where this port is available.
- ''' IDevioProvider object to that serves as storage backend for this service.
- ''' Indicates whether DevioProvider object will be automatically closed when this
- ''' instance is disposed.
- Public Sub New(ListenPort As Integer, DevioProvider As IDevioProvider, OwnsProvider As Boolean)
- MyBase.New(DevioProvider, OwnsProvider)
+ End Sub
- ListenEndPoint = New IPEndPoint(IPAddress.Any, ListenPort)
+ '''
+ ''' Creates a new service instance with enough data to later run a service that acts as server end in ImDisk/Devio
+ ''' TCP/IP based communication.
+ '''
+ ''' IP port where service should listen for client connection. Instance will listen on all
+ ''' interfaces where this port is available.
+ ''' IDevioProvider object to that serves as storage backend for this service.
+ ''' Indicates whether DevioProvider object will be automatically closed when this
+ ''' instance is disposed.
+ Public Sub New(ListenPort As Integer, DevioProvider As IDevioProvider, OwnsProvider As Boolean)
+ MyBase.New(DevioProvider, OwnsProvider)
- End Sub
+ ListenEndPoint = New IPEndPoint(IPAddress.Any, ListenPort)
- '''
- ''' Runs service that acts as server end in ImDisk/Devio TCP/IP based communication. It will first wait for
- ''' a client to connect, then serve client I/O requests and when client finally requests service to terminate, this
- ''' method returns to caller. To run service in a worker thread that automatically disposes this object after client
- ''' disconnection, call StartServiceThread() instead.
- '''
- Public Overrides Sub RunService()
+ End Sub
+
+ '''
+ ''' Runs service that acts as server end in ImDisk/Devio TCP/IP based communication. It will first wait for
+ ''' a client to connect, then serve client I/O requests and when client finally requests service to terminate, this
+ ''' method returns to caller. To run service in a worker thread that automatically disposes this object after client
+ ''' disconnection, call StartServiceThread() instead.
+ '''
+ Public Overrides Sub RunService()
- Try
- Trace.WriteLine("Setting up listener at " & ListenEndPoint.ToString())
+ Try
+ Trace.WriteLine("Setting up listener at " & ListenEndPoint.ToString())
- Dim Listener As New TcpListener(ListenEndPoint)
+ Dim Listener As New TcpListener(ListenEndPoint)
- Try
- Listener.ExclusiveAddressUse = False
- Listener.Start()
+ Try
+ Listener.ExclusiveAddressUse = False
+ Listener.Start()
- Catch ex As Exception
- Trace.WriteLine("Listen failed: " & ex.ToString())
- OnServiceInitFailed()
- Return
+ Catch ex As Exception
+ Trace.WriteLine("Listen failed: " & ex.ToString())
+ OnServiceInitFailed()
+ Return
- End Try
+ End Try
- Trace.WriteLine("Raising service ready event.")
- OnServiceReady()
+ Trace.WriteLine("Raising service ready event.")
+ OnServiceReady()
- Dim StopServiceThreadHandler As New Action(AddressOf Listener.Stop)
- AddHandler StopServiceThread, StopServiceThreadHandler
- Dim TcpSocket = Listener.AcceptSocket()
- RemoveHandler StopServiceThread, StopServiceThreadHandler
- Listener.Stop()
- Trace.WriteLine("Connection from " & TcpSocket.RemoteEndPoint.ToString())
- Dim TcpStream As New NetworkStream(TcpSocket, ownsSocket:=True)
+ Dim StopServiceThreadHandler As New Action(AddressOf Listener.Stop)
+ AddHandler StopServiceThread, StopServiceThreadHandler
+ Dim TcpSocket = Listener.AcceptSocket()
+ RemoveHandler StopServiceThread, StopServiceThreadHandler
+ Listener.Stop()
+ Trace.WriteLine("Connection from " & TcpSocket.RemoteEndPoint.ToString())
+ Dim TcpStream As New NetworkStream(TcpSocket, ownsSocket:=True)
- Dim Reader As New BinaryReader(TcpStream, Encoding.Default)
- Dim Writer As New BinaryWriter(New MemoryStream, Encoding.Default)
+ Dim Reader As New BinaryReader(TcpStream, Encoding.Default)
+ Dim Writer As New BinaryWriter(New MemoryStream, Encoding.Default)
- Dim ManagedBuffer As Byte() = Nothing
+ Dim ManagedBuffer As Byte() = Nothing
- Do
+ Do
- Dim RequestCode As IMDPROXY_REQ
+ Dim RequestCode As IMDPROXY_REQ
- Try
- RequestCode = CType(Reader.ReadUInt64(), IMDPROXY_REQ)
+ Try
+ RequestCode = CType(Reader.ReadUInt64(), IMDPROXY_REQ)
- Catch ex As EndOfStreamException
- Exit Do
+ Catch ex As EndOfStreamException
+ Exit Do
- End Try
+ End Try
- 'Trace.WriteLine("Got client request: " & RequestCode.ToString())
+ 'Trace.WriteLine("Got client request: " & RequestCode.ToString())
- Select Case RequestCode
+ Select Case RequestCode
- Case IMDPROXY_REQ.IMDPROXY_REQ_INFO
- SendInfo(Writer)
+ Case IMDPROXY_REQ.IMDPROXY_REQ_INFO
+ SendInfo(Writer)
- Case IMDPROXY_REQ.IMDPROXY_REQ_READ
- ReadData(Reader, Writer, ManagedBuffer)
+ Case IMDPROXY_REQ.IMDPROXY_REQ_READ
+ ReadData(Reader, Writer, ManagedBuffer)
- Case IMDPROXY_REQ.IMDPROXY_REQ_WRITE
- WriteData(Reader, Writer, ManagedBuffer)
+ Case IMDPROXY_REQ.IMDPROXY_REQ_WRITE
+ WriteData(Reader, Writer, ManagedBuffer)
- Case IMDPROXY_REQ.IMDPROXY_REQ_CLOSE
- Trace.WriteLine("Closing connection.")
- Return
+ Case IMDPROXY_REQ.IMDPROXY_REQ_CLOSE
+ Trace.WriteLine("Closing connection.")
+ Return
- Case Else
- Trace.WriteLine("Unsupported request code: " & RequestCode.ToString())
- Return
+ Case Else
+ Trace.WriteLine("Unsupported request code: " & RequestCode.ToString())
+ Return
- End Select
+ End Select
- 'Trace.WriteLine("Sending response and waiting for next request.")
+ 'Trace.WriteLine("Sending response and waiting for next request.")
- Writer.Seek(0, SeekOrigin.Begin)
- With DirectCast(Writer.BaseStream, MemoryStream)
- .WriteTo(TcpStream)
- .SetLength(0)
- End With
+ Writer.Seek(0, SeekOrigin.Begin)
+ With DirectCast(Writer.BaseStream, MemoryStream)
+ .WriteTo(TcpStream)
+ .SetLength(0)
+ End With
- Loop
+ Loop
- Trace.WriteLine("Client disconnected.")
+ Trace.WriteLine("Client disconnected.")
- Catch ex As Exception
- Trace.WriteLine("Unhandled exception in service thread: " & ex.ToString())
- OnServiceUnhandledException(New UnhandledExceptionEventArgs(ex, True))
+ Catch ex As Exception
+ Trace.WriteLine("Unhandled exception in service thread: " & ex.ToString())
+ OnServiceUnhandledException(New UnhandledExceptionEventArgs(ex, True))
- Finally
- OnServiceShutdown()
+ Finally
+ OnServiceShutdown()
- End Try
+ End Try
- End Sub
+ End Sub
- Private Sub SendInfo(Writer As BinaryWriter)
+ Private Sub SendInfo(Writer As BinaryWriter)
- Writer.Write(CULng(DevioProvider.Length))
- Writer.Write(CULng(REQUIRED_ALIGNMENT))
- Writer.Write(CULng(If(DevioProvider.CanWrite, IMDPROXY_FLAGS.IMDPROXY_FLAG_NONE, IMDPROXY_FLAGS.IMDPROXY_FLAG_RO)))
+ Writer.Write(CULng(DevioProvider.Length))
+ Writer.Write(CULng(REQUIRED_ALIGNMENT))
+ Writer.Write(CULng(If(DevioProvider.CanWrite, IMDPROXY_FLAGS.IMDPROXY_FLAG_NONE, IMDPROXY_FLAGS.IMDPROXY_FLAG_RO)))
- End Sub
+ End Sub
- Private Sub ReadData(Reader As BinaryReader, Writer As BinaryWriter, Data As Byte())
+ Private Sub ReadData(Reader As BinaryReader, Writer As BinaryWriter, Data As Byte())
- Dim Offset = Reader.ReadInt64()
- Dim ReadLength = CInt(Reader.ReadUInt64())
- If Data Is Nothing OrElse Data.Length < ReadLength Then
- Array.Resize(Data, ReadLength)
- End If
- Dim WriteLength As ULong
- Dim ErrorCode As ULong
+ Dim Offset = Reader.ReadInt64()
+ Dim ReadLength = CInt(Reader.ReadUInt64())
+ If Data Is Nothing OrElse Data.Length < ReadLength Then
+ Array.Resize(Data, ReadLength)
+ End If
+ Dim WriteLength As ULong
+ Dim ErrorCode As ULong
- Try
- WriteLength = CULng(DevioProvider.Read(Data, 0, ReadLength, Offset))
- ErrorCode = 0
+ Try
+ WriteLength = CULng(DevioProvider.Read(Data, 0, ReadLength, Offset))
+ ErrorCode = 0
- Catch ex As Exception
- Trace.WriteLine(ex.ToString())
- Trace.WriteLine("Read request at " & Offset.ToString("X").PadLeft(8, "0"c) & " for " & ReadLength & " bytes.")
- ErrorCode = 1
- WriteLength = 0
+ Catch ex As Exception
+ Trace.WriteLine(ex.ToString())
+ Trace.WriteLine($"Read request at 0x{Offset:X8} for {ReadLength} bytes.")
+ ErrorCode = 1
+ WriteLength = 0
- End Try
+ End Try
- Writer.Write(ErrorCode)
- Writer.Write(WriteLength)
- If WriteLength > 0 Then
- Writer.Write(Data, 0, CInt(WriteLength))
- End If
+ Writer.Write(ErrorCode)
+ Writer.Write(WriteLength)
+ If WriteLength > 0 Then
+ Writer.Write(Data, 0, CInt(WriteLength))
+ End If
- End Sub
+ End Sub
- Private Sub WriteData(Reader As BinaryReader, Writer As BinaryWriter, Data As Byte())
+ Private Sub WriteData(Reader As BinaryReader, Writer As BinaryWriter, Data As Byte())
- Dim Offset = Reader.ReadInt64()
- Dim Length = Reader.ReadUInt64()
- If Data Is Nothing OrElse Data.Length < Length Then
- Array.Resize(Data, CInt(Length))
- End If
+ Dim Offset = Reader.ReadInt64()
+ Dim Length = Reader.ReadUInt64()
+ If Data Is Nothing OrElse Data.Length < Length Then
+ Array.Resize(Data, CInt(Length))
+ End If
- Dim ReadLength = Reader.Read(Data, 0, CInt(Length))
- Dim WriteLength As ULong
- Dim ErrorCode As ULong
+ Dim ReadLength = Reader.Read(Data, 0, CInt(Length))
+ Dim WriteLength As ULong
+ Dim ErrorCode As ULong
- Try
- WriteLength = CULng(DevioProvider.Write(Data, 0, ReadLength, Offset))
- ErrorCode = 0
+ Try
+ WriteLength = CULng(DevioProvider.Write(Data, 0, ReadLength, Offset))
+ ErrorCode = 0
- Catch ex As Exception
- Trace.WriteLine(ex.ToString())
- Trace.WriteLine("Write request at " & Offset.ToString("X").PadLeft(8, "0"c) & " for " & Length & " bytes.")
- ErrorCode = 1
- WriteLength = 0
+ Catch ex As Exception
+ Trace.WriteLine(ex.ToString())
+ Trace.WriteLine($"Write request at 0x{Offset:X8} for {Length} bytes.")
+ ErrorCode = 1
+ WriteLength = 0
- End Try
+ End Try
- Writer.Write(ErrorCode)
- Writer.Write(WriteLength)
+ Writer.Write(ErrorCode)
+ Writer.Write(WriteLength)
- End Sub
+ End Sub
- Protected Overrides ReadOnly Property ImDiskProxyObjectName As String
- Get
- Dim EndPoint = ListenEndPoint
- If EndPoint.Address.Equals(IPAddress.Any) Then
- EndPoint = New IPEndPoint(IPAddress.Loopback, EndPoint.Port)
- End If
- Return EndPoint.ToString()
- End Get
- End Property
+ Protected Overrides ReadOnly Property ImDiskProxyObjectName As String
+ Get
+ Dim EndPoint = ListenEndPoint
+ If EndPoint.Address.Equals(IPAddress.Any) Then
+ EndPoint = New IPEndPoint(IPAddress.Loopback, EndPoint.Port)
+ End If
+ Return EndPoint.ToString()
+ End Get
+ End Property
- Protected Overrides ReadOnly Property ImDiskProxyModeFlags As ImDiskFlags
- Get
- Return ImDiskFlags.TypeProxy Or ImDiskFlags.ProxyTypeTCP
- End Get
- End Property
+ Protected Overrides ReadOnly Property ImDiskProxyModeFlags As ImDiskFlags
+ Get
+ Return ImDiskFlags.TypeProxy Or ImDiskFlags.ProxyTypeTCP
+ End Get
+ End Property
- End Class
+ End Class
End Namespace
diff --git a/ImDiskNet/DevioNet/app.config b/ImDiskNet/DevioNet/app.config
new file mode 100644
index 0000000..6b91abd
--- /dev/null
+++ b/ImDiskNet/DevioNet/app.config
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImDiskNet/DevioNet/packages.config b/ImDiskNet/DevioNet/packages.config
new file mode 100644
index 0000000..0a5ecf9
--- /dev/null
+++ b/ImDiskNet/DevioNet/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImDiskNet/Directory.build.props b/ImDiskNet/Directory.build.props
new file mode 100644
index 0000000..9b729d8
--- /dev/null
+++ b/ImDiskNet/Directory.build.props
@@ -0,0 +1,34 @@
+
+
+
+
+ LTR.IO
+ ..\$(Configuration)\
+ true
+ true
+ false
+ true
+ 9.0
+ portable
+ false
+ true
+ On
+ On
+ On
+
+
+
+
+
+ ImDisk Virtual Disk Driver
+ Olof Lagerkvist, LTR Data
+ ImDisk Virtual Disk Driver
+ Copyright © Olof Lagerkvist, 2011 - 2021
+
+ 2.1.013.0
+ 1.0.009.0
+ 1.0.009.0
+
+
+
+
diff --git a/ImDiskNet/DiscUtilsDevio/DiscUtilsDevio.vbproj b/ImDiskNet/DiscUtilsDevio/DiscUtilsDevio.vbproj
index 53c9638..ca3fa9b 100644
--- a/ImDiskNet/DiscUtilsDevio/DiscUtilsDevio.vbproj
+++ b/ImDiskNet/DiscUtilsDevio/DiscUtilsDevio.vbproj
@@ -1,154 +1,48 @@

-
+
+
+
- Debug
- x86
-
-
-
-
- {0E6ECB44-49AE-4732-AA27-4566258F1B96}
+
Exe
- LTR.IO.ImDisk.Devio.DiscUtilsDevio.ServerModule
LTR.IO.ImDisk.Devio.DiscUtilsDevio
- DiscUtilsDevio
- 512
- Console
- v4.0
-
-
+ DiscUtilsDevio
+ ImDisk Devio for DiscUtils library
+
+ net40;net5.0-windows
+
-
- x86
- true
- full
- true
- true
- bin\Debug\
- DiscUtilsDevio.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
-
-
- x86
- pdbonly
- false
- true
- true
- bin\Release\
- DiscUtilsDevio.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
-
-
- On
-
-
- Binary
-
-
- On
-
-
- On
-
-
- true
- true
- true
- ..\Debug\
- DiscUtilsDevio.xml
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
- full
- AnyCPU
- true
- true
-
-
- true
- ..\Release\
- DiscUtilsDevio.xml
- true
- 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
- pdbonly
- AnyCPU
-
-
-
- False
- .\DiscUtils.dll
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
- True
- Application.myapp
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
-
-
- VbMyResourcesResXFileCodeGenerator
- Resources.Designer.vb
- My.Resources
- Designer
-
-
-
-
- Designer
-
-
- MyApplicationCodeGenerator
- Application.Designer.vb
-
-
- SettingsSingleFileGenerator
- My
- Settings.Designer.vb
-
-
-
-
- {C8131F7E-E240-4A1B-8D3D-FC4E5DBED050}
- DevioNet
-
-
- {3EFCB6F8-EF7E-4F60-A0DE-BB197240FCC9}
- ImDiskNet
-
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Core.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Dmg.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Streams.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Vdi.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Vhd.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Vhdx.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Vmdk.dll
+
+
+ ..\DiscUtils\$(TargetFramework)\DiscUtils.Xva.dll
+
-
-
-
\ No newline at end of file
+
+
diff --git a/ImDiskNet/DiscUtilsDevio/GlobalSuppressions.vb b/ImDiskNet/DiscUtilsDevio/GlobalSuppressions.vb
new file mode 100644
index 0000000..fafdca9
--- /dev/null
+++ b/ImDiskNet/DiscUtilsDevio/GlobalSuppressions.vb
@@ -0,0 +1,9 @@
+' This file is used by Code Analysis to maintain SuppressMessage
+' attributes that are applied to this project.
+' Project-level suppressions either have no target or are given
+' a specific target and scoped to a namespace, type, member, etc.
+
+Imports System.Diagnostics.CodeAnalysis
+
+
+
diff --git a/ImDiskNet/DiscUtilsDevio/My Project/AssemblyInfo.vb b/ImDiskNet/DiscUtilsDevio/My Project/AssemblyInfo.vb
index 116e34e..041c092 100644
--- a/ImDiskNet/DiscUtilsDevio/My Project/AssemblyInfo.vb
+++ b/ImDiskNet/DiscUtilsDevio/My Project/AssemblyInfo.vb
@@ -8,28 +8,8 @@ Imports System.Runtime.InteropServices
' Review the values of the assembly attributes
-
-
-
-
-
-
-
'The following GUID is for the ID of the typelib if this project is exposed to COM
-' Version information for an assembly consists of the following four values:
-'
-' Major Version
-' Minor Version
-' Build Number
-' Revision
-'
-' You can specify all the values or you can default the Build and Revision Numbers
-' by using the '*' as shown below:
-'
-
-
-
diff --git a/ImDiskNet/DiscUtilsDevio/My Project/Settings.Designer.vb b/ImDiskNet/DiscUtilsDevio/My Project/Settings.Designer.vb
deleted file mode 100644
index ca8b8ea..0000000
--- a/ImDiskNet/DiscUtilsDevio/My Project/Settings.Designer.vb
+++ /dev/null
@@ -1,73 +0,0 @@
-'------------------------------------------------------------------------------
-'
-' This code was generated by a tool.
-' Runtime Version:4.0.30319.239
-'
-' Changes to this file may cause incorrect behavior and will be lost if
-' the code is regenerated.
-'
-'------------------------------------------------------------------------------
-
-Option Strict On
-Option Explicit On
-
-
-Namespace My
-
-
- Partial Friend NotInheritable Class MySettings
- Inherits Global.System.Configuration.ApplicationSettingsBase
-
- Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()), MySettings)
-
-#Region "My.Settings Auto-Save Functionality"
-#If _MyType = "WindowsForms" Then
- Private Shared addedHandler As Boolean
-
- Private Shared addedHandlerLockObject As New Object
-
-
- Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
- If My.Application.SaveMySettingsOnExit Then
- My.Settings.Save()
- End If
- End Sub
-#End If
-#End Region
-
- Public Shared ReadOnly Property [Default]() As MySettings
- Get
-
-#If _MyType = "WindowsForms" Then
- If Not addedHandler Then
- SyncLock addedHandlerLockObject
- If Not addedHandler Then
- AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
- addedHandler = True
- End If
- End SyncLock
- End If
-#End If
- Return defaultInstance
- End Get
- End Property
- End Class
-End Namespace
-
-Namespace My
-
-
- Friend Module MySettingsProperty
-
-
- Friend ReadOnly Property Settings() As Global.LTR.IO.ImDisk.Devio.DiscUtilsDevio.My.MySettings
- Get
- Return Global.LTR.IO.ImDisk.Devio.DiscUtilsDevio.My.MySettings.Default
- End Get
- End Property
- End Module
-End Namespace
diff --git a/ImDiskNet/DiscUtilsDevio/ServerModule.vb b/ImDiskNet/DiscUtilsDevio/ServerModule.vb
index d6df4c8..0ab0b82 100644
--- a/ImDiskNet/DiscUtilsDevio/ServerModule.vb
+++ b/ImDiskNet/DiscUtilsDevio/ServerModule.vb
@@ -1,9 +1,25 @@
-Imports DiscUtils
-
-Module ServerModule
+Imports System.IO
+Imports System.Net
+Imports System.Reflection
+Imports System.Threading
+Imports DiscUtils
+Imports DiscUtils.Setup
+Imports LTR.IO.ImDisk.Devio.Server.Providers
+Imports LTR.IO.ImDisk.Devio.Server.Services
+
+Public Module ServerModule
+
+ Private ReadOnly asms As New List(Of Assembly) From {
+ GetType(Dmg.Disk).Assembly,
+ GetType(Vdi.Disk).Assembly,
+ GetType(Vmdk.Disk).Assembly,
+ GetType(Vhd.Disk).Assembly,
+ GetType(Vhdx.Disk).Assembly,
+ GetType(Xva.Disk).Assembly
+ }
- Sub Main(args As String())
+ Friend Sub Main(args As String())
Try
SafeMain(args)
@@ -22,220 +38,247 @@ Module ServerModule
End Sub
- Sub SafeMain(args As String())
+ Public Sub SafeMain(ParamArray args As String())
- Dim DeviceName As String = Nothing
- Dim ObjectName As String = Nothing
- Dim ListenAddress As IPAddress = IPAddress.Any
- Dim ListenPort As Integer
- Dim BufferSize As Long = DevioShmService.DefaultBufferSize
- Dim DiskAccess As FileAccess = FileAccess.ReadWrite
- Dim PartitionNumber As Integer? = Nothing
- Dim Mount As Boolean = False
- Dim MountPoint As String = Nothing
- Dim ShowHelp As Boolean = False
+ Dim device_name As String = Nothing
+ Dim object_name As String = Nothing
+ Dim listen_address As IPAddress = IPAddress.Any
+ Dim listen_port As Integer
+ Dim buffer_size As Long = DevioShmService.DefaultBufferSize
+ Dim disk_access As FileAccess = FileAccess.ReadWrite
+ Dim partition_number As Integer? = Nothing
+ Dim mount As Boolean = False
+ Dim mount_point As String = Nothing
+ Dim show_help As Boolean = False
For Each arg In args
If arg.StartsWith("/name=", StringComparison.OrdinalIgnoreCase) Then
- ObjectName = arg.Substring("/name=".Length)
+ object_name = arg.Substring("/name=".Length)
ElseIf arg.StartsWith("/ipaddress=", StringComparison.OrdinalIgnoreCase) Then
- ListenAddress = IPAddress.Parse(arg.Substring("/ipaddress=".Length))
+ listen_address = IPAddress.Parse(arg.Substring("/ipaddress=".Length))
ElseIf arg.StartsWith("/port=", StringComparison.OrdinalIgnoreCase) Then
- ListenPort = Integer.Parse(arg.Substring("/port=".Length))
+ listen_port = Integer.Parse(arg.Substring("/port=".Length), Globalization.NumberFormatInfo.InvariantInfo)
ElseIf arg.StartsWith("/buffersize=", StringComparison.OrdinalIgnoreCase) Then
- BufferSize = Long.Parse(arg.Substring("/buffersize=".Length))
+ buffer_size = Long.Parse(arg.Substring("/buffersize=".Length), Globalization.NumberFormatInfo.InvariantInfo)
ElseIf arg.StartsWith("/partition=", StringComparison.OrdinalIgnoreCase) Then
- PartitionNumber = Integer.Parse(arg.Substring("/partition=".Length))
+ partition_number = Integer.Parse(arg.Substring("/partition=".Length), Globalization.NumberFormatInfo.InvariantInfo)
ElseIf arg.StartsWith("/filename=", StringComparison.OrdinalIgnoreCase) Then
- DeviceName = arg.Substring("/filename=".Length)
+ device_name = arg.Substring("/filename=".Length)
ElseIf arg.Equals("/readonly", StringComparison.OrdinalIgnoreCase) Then
- DiskAccess = FileAccess.Read
+ disk_access = FileAccess.Read
ElseIf arg.Equals("/mount", StringComparison.OrdinalIgnoreCase) Then
- Mount = True
+ mount = True
ElseIf arg.Equals("/trace", StringComparison.OrdinalIgnoreCase) Then
Trace.Listeners.Add(New ConsoleTraceListener)
ElseIf arg.StartsWith("/mount=", StringComparison.OrdinalIgnoreCase) Then
- Mount = True
- MountPoint = arg.Substring("/mount=".Length)
- ElseIf arg = "/?" OrElse arg.Equals("/help", StringComparison.OrdinalIgnoreCase) Then
- ShowHelp = True
+ mount = True
+ mount_point = arg.Substring("/mount=".Length)
+ ElseIf arg.StartsWith("/asm=", StringComparison.OrdinalIgnoreCase) Then
+ Dim asmname = AssemblyName.GetAssemblyName(arg.Substring("/asm=".Length))
+ asms.Add(Assembly.Load(asmname))
+ ElseIf arg.Equals("/?", StringComparison.Ordinal) OrElse arg.Equals("/help", StringComparison.OrdinalIgnoreCase) Then
+ show_help = True
Exit For
Else
Console.WriteLine("Unsupported switch: " & arg)
- ShowHelp = True
+ show_help = True
Exit For
End If
Next
If _
- ShowHelp OrElse
- String.IsNullOrEmpty(DeviceName) Then
-
- Console.WriteLine("Syntax:" & Environment.NewLine &
- "DiscUtilsDevio /name=objectname [/buffersize=bytes] [/partition=number]" & Environment.NewLine &
- " /filename=imagefilename [/readonly] [/mount[=d:]] [/trace]" & Environment.NewLine &
- Environment.NewLine &
- "DiscUtilsDevio [/name=objectname] [/buffersize=bytes] [/partition=number]" & Environment.NewLine &
- " /filename=imagefilename [/readonly] /mount[=d:] [/trace]" & Environment.NewLine &
- Environment.NewLine &
- "DiscUtilsDevio [/ipaddress=address] /port=tcpport [/partition=number]" & Environment.NewLine &
- " /filename=imagefilename [/readonly] [/mount[=d:]] [/trace]")
+ show_help OrElse
+ String.IsNullOrEmpty(device_name) Then
- Return
+ Dim msg = "Syntax:
+DiscUtilsDevio /name=objectname [/buffersize=bytes] [/partition=number] /filename=imagefilename [/readonly] [/mount[=d:]] [/trace]
- End If
+DiscUtilsDevio [/name=objectname] [/buffersize=bytes] [/partition=number] /filename=imagefilename [/readonly] /mount[=d:] [/trace]
- Console.WriteLine("Opening image " & DeviceName)
+DiscUtilsDevio [/ipaddress=address] /port=tcpport [/partition=number] /filename=imagefilename [/readonly] [/mount[=d:]] [/trace]
- Dim Device = VirtualDisk.OpenDisk(DeviceName, DiskAccess)
+You can additionally use the /asm=path switch to load an additional DiscUtils compatible assembly file that provides support for more virtual disk formats."
- If Device Is Nothing Then
- Dim fs As New FileStream(DeviceName, FileMode.Open, DiskAccess, FileShare.Read Or FileShare.Delete)
- Try
- Device = New Dmg.Disk(fs, Ownership.Dispose)
- Catch
- fs.Dispose()
- End Try
- End If
+ msg = LineFormat(msg, 4)
+
+ Console.WriteLine(msg)
- If Device Is Nothing Then
- Console.WriteLine("Image not recognized by DiscUtils." & Environment.NewLine &
- Environment.NewLine &
- "Formats currently supported: " & String.Join(", ", VirtualDisk.SupportedDiskTypes.ToArray()),
- "Error")
Return
- End If
- Dim Table As Partitions.PartitionTable = Nothing
- Console.WriteLine("Image type class: " & Device.GetType().ToString())
- If Device.IsPartitioned Then
- Table = Device.Partitions
- End If
- If Table Is Nothing Then
- Console.WriteLine("Unknown partition table format or partition table not found.")
- Else
- Console.WriteLine("Partition table class: " & Table.GetType().ToString())
- End If
- Console.WriteLine("Image virtual size is " & Device.Capacity & " bytes")
- If Device.Geometry Is Nothing Then
- Console.WriteLine("Image sector size is unknown")
- Else
- Console.WriteLine("Image sector size is " & Device.Geometry.BytesPerSector & " bytes")
End If
- Dim DiskStream As Stream
+ For Each asm In asms.Distinct()
+
+ Trace.WriteLine($"Registering assembly {asm.GetName().Name}...")
+
+ SetupHelper.RegisterAssembly(asm)
+
+ Next
+
+ Console.WriteLine($"Opening image {device_name}")
+
+ Using device = VirtualDisk.OpenDisk(device_name, disk_access)
+
+ If device Is Nothing Then
+
+ Console.WriteLine($"Image not recognized by DiscUtils.
+
+Formats currently supported: {String.Join(", ", VirtualDiskManager.SupportedDiskTypes.ToArray())}")
- If PartitionNumber.HasValue = False Then
- If Table IsNot Nothing Then
- PartitionNumber = 1
- Console.WriteLine("Partition table found.")
+ Return
+
+ End If
+
+ Dim partition_table As Partitions.PartitionTable = Nothing
+
+ Console.WriteLine($"Image type class: {device.GetType()}")
+
+ If device.IsPartitioned Then
+ partition_table = device.Partitions
+ End If
+
+ If partition_table Is Nothing Then
+ Console.WriteLine("Unknown partition table format or partition table not found.")
Else
- PartitionNumber = 0
- Console.WriteLine("Partition table not found.")
+ Console.WriteLine($"Partition table class: {partition_table.GetType()}")
End If
- End If
- If PartitionNumber = 0 Then
- If Device IsNot Nothing Then
- DiskStream = Device.Content
+ Console.WriteLine($"Image virtual size is {device.Capacity} bytes")
+
+ If device.Geometry Is Nothing Then
+ Console.WriteLine("Image sector size is unknown")
Else
- Console.WriteLine("Raw image access for this format is not supported by DiscUtils." & Environment.NewLine &
- Environment.NewLine &
- "Formats currently supported: " & String.Join(", ", VirtualDisk.SupportedDiskTypes.ToArray()))
- Return
+ Console.WriteLine($"Image sector size is {device.Geometry.BytesPerSector} bytes")
End If
- Console.WriteLine("Using entire image file: " & DeviceName)
- Else
- If Table Is Nothing Then
- Console.WriteLine("Partition table not found in image.")
- Return
+
+ Dim disk_stream As Stream
+
+ If partition_number.HasValue = False Then
+ If partition_table IsNot Nothing Then
+ partition_number = 1
+ Console.WriteLine("Partition table found.")
+ Else
+ partition_number = 0
+ Console.WriteLine("Partition table not found.")
+ End If
End If
- If PartitionNumber > Table.Count Then
- Console.WriteLine("Partition " & PartitionNumber & " not defined in partition table.")
- Return
+
+ If partition_number = 0 Then
+ If device.Content Is Nothing Then
+ Console.WriteLine($"Raw image access for this format is not supported by DiscUtils.
+
+Formats currently supported: {String.Join(", ", VirtualDiskManager.SupportedDiskTypes.ToArray())}")
+ Return
+ End If
+
+ disk_stream = device.Content
+
+ Console.WriteLine($"Using entire image file: {device_name}")
+ Else
+ If partition_table Is Nothing Then
+ Console.WriteLine("Partition table not found in image.")
+ Return
+ End If
+
+ If partition_number > partition_table.Count Then
+ Console.WriteLine($"Partition {partition_number} not defined in partition table.")
+ Return
+ End If
+
+ disk_stream = partition_table(partition_number.Value - 1).Open()
+
+ Console.WriteLine($"Using partition {partition_number}")
End If
- DiskStream = Table(PartitionNumber.Value - 1).Open()
- Console.WriteLine("Using partition " & PartitionNumber)
- End If
- Console.WriteLine("Used size is " & DiskStream.Length & " bytes")
- If DiskStream.CanWrite Then
- Console.WriteLine("Read/write mode.")
- Else
- Console.WriteLine("Read-only mode.")
- End If
+ Console.WriteLine($"Used size is {disk_stream.Length} bytes")
- Dim Service As DevioServiceBase
- Dim Provider As New DevioProviderFromStream(DiskStream, ownsStream:=True)
+ If disk_stream.CanWrite Then
+ Console.WriteLine("Read/write mode.")
+ Else
+ Console.WriteLine("Read-only mode.")
+ End If
- If Not String.IsNullOrEmpty(ObjectName) Then
+ Dim service As DevioServiceBase
- Service = New DevioShmService(ObjectName, Provider, OwnsProvider:=True, BufferSize:=BufferSize)
+ Using provider As New DevioProviderFromStream(disk_stream, ownsStream:=True)
- ElseIf ListenPort <> 0 Then
+ If Not String.IsNullOrEmpty(object_name) Then
- Service = New DevioTcpService(ListenAddress, ListenPort, Provider, OwnsProvider:=True)
+ service = New DevioShmService(object_name, provider, OwnsProvider:=True, BufferSize:=buffer_size)
- ElseIf Mount Then
+ ElseIf listen_port <> 0 Then
- Service = New DevioShmService(Provider, OwnsProvider:=True, BufferSize:=BufferSize)
+ service = New DevioTcpService(listen_address, listen_port, provider, OwnsProvider:=True)
- Else
+ ElseIf mount Then
- Provider.Dispose()
- Console.WriteLine("Shared memory object name or TCP/IP port must be specified.")
- Return
+ service = New DevioShmService(provider, OwnsProvider:=True, BufferSize:=buffer_size)
- End If
+ Else
- If Mount Then
- If "#:".Equals(MountPoint, StringComparison.Ordinal) Then
- Dim drive_letter = ImDiskAPI.FindFreeDriveLetter()
- If drive_letter = Nothing Then
- Console.Error.WriteLine("No drive letter available")
+ provider.Dispose()
+
+ Console.WriteLine("Shared memory object name or TCP/IP port must be specified.")
Return
- End If
- MountPoint = {drive_letter, ":"c}
- Console.WriteLine("Selected " & MountPoint & " as drive letter mount point")
- End If
- Console.WriteLine("Opening image file and mounting as virtual disk...")
- Service.StartServiceThreadAndMountImDisk(ImDiskFlags.Auto, MountPoint)
- Console.WriteLine("Virtual disk created. Press Ctrl+C to remove virtual disk and exit.")
- Else
- Console.WriteLine("Opening image file...")
- Service.StartServiceThread()
- Console.WriteLine("Image file opened, waiting for incoming connections. Press Ctrl+C to exit.")
- End If
- AddHandler Console.CancelKeyPress,
- Sub(sender, e)
- ThreadPool.QueueUserWorkItem(
- Sub()
+ End If
- If Not Monitor.TryEnter(break_lock) Then
- Return
+ Using service
+
+ If mount Then
+ If "#:".Equals(mount_point, StringComparison.Ordinal) Then
+ Dim drive_letter = ImDiskAPI.FindFreeDriveLetter()
+ If drive_letter = Nothing Then
+ Console.Error.WriteLine("No drive letter available")
+ Return
+ End If
+ mount_point = {drive_letter, ":"c}
+ Console.WriteLine($"Selected {mount_point} as drive letter mount point")
+ End If
+ Console.WriteLine("Opening image file and mounting as virtual disk...")
+ service.StartServiceThreadAndMountImDisk(ImDiskFlags.Auto, mount_point)
+ Console.WriteLine("Virtual disk created. Press Ctrl+C to remove virtual disk and exit.")
+ Else
+ Console.WriteLine("Opening image file...")
+ service.StartServiceThread()
+ Console.WriteLine("Image file opened, waiting for incoming connections. Press Ctrl+C to exit.")
End If
- Try
- Console.WriteLine("Stopping service...")
- Service.Dispose()
+ AddHandler Console.CancelKeyPress,
+ Sub(sender, e)
+ ThreadPool.QueueUserWorkItem(
+ Sub()
+
+ If Not Monitor.TryEnter(break_lock) Then
+ Return
+ End If
+
+ Try
+ Console.WriteLine("Stopping service...")
+ service.Dispose()
- Finally
- Monitor.Exit(break_lock)
+ Finally
+ Monitor.Exit(break_lock)
+ End Try
+ End Sub)
+
+ Try
+ e.Cancel = True
+ Catch
End Try
- End Sub)
- Try
- e.Cancel = True
- Catch
- End Try
+ End Sub
+
+ service.WaitForServiceThreadExit()
+
+ Console.WriteLine("Service stopped.")
- End Sub
+ End Using
- Service.WaitForServiceThreadExit()
+ End Using
- Console.WriteLine("Service stopped.")
+ End Using
End Sub
diff --git a/ImDiskNet/DiscUtilsDevio/app.config b/ImDiskNet/DiscUtilsDevio/app.config
new file mode 100644
index 0000000..6b91abd
--- /dev/null
+++ b/ImDiskNet/DiscUtilsDevio/app.config
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImDiskNet/DiscUtilsDevio/packages.config b/ImDiskNet/DiscUtilsDevio/packages.config
new file mode 100644
index 0000000..0a5ecf9
--- /dev/null
+++ b/ImDiskNet/DiscUtilsDevio/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImDiskNet/ImDiskNet.inf b/ImDiskNet/ImDiskNet.inf
new file mode 100644
index 0000000..506adda
--- /dev/null
+++ b/ImDiskNet/ImDiskNet.inf
@@ -0,0 +1,69 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 03/24/2020,2.1.0.00068
+CatalogFile = ImDiskNet.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk .NET API and tools"
+
+
+[SourceDisksFiles.x86]
+ImDiskNet.dll = 1, Release
+DevioNet.dll = 1, Release
+DiscUtils.dll = 1, Release
+DiscUtilsDevio.exe = 1, Release
+
+[SourceDisksFiles.ia64]
+ImDiskNet.dll = 1, Release
+DevioNet.dll = 1, Release
+DiscUtils.dll = 1, Release
+DiscUtilsDevio.exe = 1, Release
+
+[SourceDisksFiles.amd64]
+ImDiskNet.dll = 1, Release
+DevioNet.dll = 1, Release
+DiscUtils.dll = 1, Release
+DiscUtilsDevio.exe = 1, Release
+
+[SourceDisksFiles.arm]
+ImDiskNet.dll = 1, Release
+DevioNet.dll = 1, Release
+DiscUtils.dll = 1, Release
+DiscUtilsDevio.exe = 1, Release
+
+[SourceDisksFiles.arm64]
+ImDiskNet.dll = 1, Release
+DevioNet.dll = 1, Release
+DiscUtils.dll = 1, Release
+DiscUtilsDevio.exe = 1, Release
+
+[DestinationDirs]
+ExeFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ExeFiles
+
+
+[ExeFiles]
+DiscUtilsDevio.exe
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDiskNet, , ImDiskNet
+
+
+[ImDiskNet]
+DisplayName = "ImDiskNet"
+StartType = 2
+ServiceType = 16
+ErrorControl = 0
+ServiceBinary = %11%\DiscUtilsDevio.exe
diff --git a/ImDiskNet/ImDiskNet.shfbproj b/ImDiskNet/ImDiskNet.shfbproj
deleted file mode 100644
index 142ceda..0000000
--- a/ImDiskNet/ImDiskNet.shfbproj
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {ff9b3f4a-c5d0-4215-9d57-120a2e5974ca}
- 1.9.3.0
-
- Documentation
- Documentation
- Documentation
-
- .\Help\
- ImDisk Virtual Disk Driver API
- en-US
- HtmlHelp1, MSHelpViewer, Website
- ImDisk Virtual Disk Driver API
- None
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ImDiskNet/ImDiskNet.sln b/ImDiskNet/ImDiskNet.sln
index db0dfbf..3490677 100644
--- a/ImDiskNet/ImDiskNet.sln
+++ b/ImDiskNet/ImDiskNet.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29920.165
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ImDiskNet", "ImDiskNet\ImDiskNet.vbproj", "{3EFCB6F8-EF7E-4F60-A0DE-BB197240FCC9}"
EndProject
@@ -15,6 +15,11 @@ Project("{7CF6DF6D-3B04-46F8-A40B-537D21BCA0B4}") = "ImDiskNetHelpBuilder", "ImD
{3EFCB6F8-EF7E-4F60-A0DE-BB197240FCC9} = {3EFCB6F8-EF7E-4F60-A0DE-BB197240FCC9}
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{24EB0931-A36C-425E-ACEF-7B8E400E8C58}"
+ ProjectSection(SolutionItems) = preProject
+ Directory.build.props = Directory.build.props
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -55,4 +60,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {DF55C9DC-F716-4394-8B6D-DEEBB8A9FE17}
+ EndGlobalSection
EndGlobal
diff --git a/ImDiskNet/ImDiskNet/GlobalSuppressions.vb b/ImDiskNet/ImDiskNet/GlobalSuppressions.vb
new file mode 100644
index 0000000..da1da05
--- /dev/null
+++ b/ImDiskNet/ImDiskNet/GlobalSuppressions.vb
@@ -0,0 +1,9 @@
+' This file is used by Code Analysis to maintain SuppressMessage
+' attributes that are applied to this project.
+' Project-level suppressions either have no target or are given
+' a specific target and scoped to a namespace, type, member, etc.
+
+Imports System.Diagnostics.CodeAnalysis
+
+
+
diff --git a/ImDiskNet/ImDiskNet/IO/ConsoleSupport.vb b/ImDiskNet/ImDiskNet/IO/ConsoleSupport.vb
new file mode 100644
index 0000000..e3c636b
--- /dev/null
+++ b/ImDiskNet/ImDiskNet/IO/ConsoleSupport.vb
@@ -0,0 +1,68 @@
+Imports System.Runtime.CompilerServices
+Imports System.Text
+
+Namespace ImDisk
+
+ Public Module ConsoleSupport
+
+ Public Function LineFormat(message As String, Optional IndentWidth As Integer = 0, Optional LineWidth As Integer? = Nothing, Optional WordDelimiter As Char = " "c, Optional FillChar As Char = " "c) As String
+
+ If message Is Nothing Then
+ Throw New ArgumentNullException(NameOf(message))
+ End If
+
+ Dim Width As Integer
+
+ If LineWidth.HasValue Then
+ Width = LineWidth.Value
+ Else
+ If NativeFileIO.UnsafeNativeMethods.GetFileType(NativeFileIO.UnsafeNativeMethods.GetStdHandle(NativeFileIO.StdHandle.Output)) <> NativeFileIO.Win32FileType.Character Then
+ Width = 79
+ Else
+ Width = Console.WindowWidth - 1
+ End If
+ End If
+
+ Dim origLines = message.Replace(Microsoft.VisualBasic.vbCr, "").Split({Microsoft.VisualBasic.vbLf(0)})
+
+ Dim resultLines As New List(Of String)(origLines.Length)
+
+ Dim result As New StringBuilder
+
+ Dim line As New StringBuilder(Width)
+
+ For Each origLine In origLines
+
+ result.Length = 0
+ line.Length = 0
+
+ For Each Word In origLine.Split(WordDelimiter)
+ If Word.Length >= Width Then
+ result.AppendLine(Word)
+ Continue For
+ End If
+ If Word.Length + line.Length >= Width Then
+ result.AppendLine(line.ToString())
+ line.Length = 0
+ line.Append(FillChar, IndentWidth)
+ ElseIf line.Length > 0 Then
+ line.Append(WordDelimiter)
+ End If
+ line.Append(Word)
+ Next
+
+ If line.Length > 0 Then
+ result.Append(line.ToString())
+ End If
+
+ resultLines.Add(result.ToString())
+
+ Next
+
+ Return String.Join(Environment.NewLine, resultLines.ToArray())
+
+ End Function
+
+ End Module
+
+End Namespace
diff --git a/ImDiskNet/ImDiskNet/IO/PinnedBuffer.vb b/ImDiskNet/ImDiskNet/IO/PinnedBuffer.vb
new file mode 100644
index 0000000..71db77a
--- /dev/null
+++ b/ImDiskNet/ImDiskNet/IO/PinnedBuffer.vb
@@ -0,0 +1,321 @@
+Imports System.Runtime.InteropServices
+Imports System.Runtime.InteropServices.Marshal
+Imports System.Security
+Imports System.Security.Permissions
+Imports Microsoft.Win32.SafeHandles
+
+Namespace IO
+
+ '''
+ ''' Pins a value object for unmanaged use.
+ '''
+
+
+
+ Public Class PinnedBuffer
+#If NET40_OR_GREATER OrElse Not NETFRAMEWORK Then
+ Inherits SafeBuffer
+#Else
+ Inherits SafeHandleZeroOrMinusOneIsInvalid
+
+ Public ReadOnly Property ByteLength As ULong
+
+ Protected Sub Initialize(size As ULong)
+ _ByteLength = size
+ End Sub
+#End If
+
+
+ Protected _gchandle As GCHandle
+
+ Protected Sub New()
+ MyBase.New(ownsHandle:=True)
+
+ End Sub
+
+ Public ReadOnly Property Offset As Integer
+
+ Get
+ If IntPtr.Size > 4 Then
+ Return CInt(DangerousGetHandle().ToInt64() - _gchandle.AddrOfPinnedObject().ToInt64())
+ Else
+ Return DangerousGetHandle().ToInt32() - _gchandle.AddrOfPinnedObject().ToInt32()
+ End If
+ End Get
+ End Property
+
+ '''
+ ''' Initializes a new instance with an existing type T object and pins memory
+ ''' position.
+ '''
+ ''' Existing object to marshal to unmanaged memory.
+
+ Public Shared Function Create(obj As String) As PinnedString
+ Return New PinnedString(obj)
+ End Function
+
+ '''
+ ''' Initializes a new instance with an existing type T array and pins memory
+ ''' position.
+ '''
+ ''' Existing object to marshal to unmanaged memory.
+
+ Public Shared Function Create(Of T As Structure)(obj As T()) As PinnedBuffer(Of T)
+ Return New PinnedBuffer(Of T)(obj)
+ End Function
+
+#If Not NET_CORE Then
+
+ Public Shared Function PtrToStructure(Of T)(ptr As IntPtr) As T
+ Return DirectCast(Marshal.PtrToStructure(ptr, GetType(T)), T)
+ End Function
+
+
+ Public Shared Sub DestroyStructure(Of T)(ptr As IntPtr)
+ Marshal.DestroyStructure(ptr, GetType(T))
+ End Sub
+#End If
+
+
+ Public Shared Function Serialize(Of T)(obj As T) As Byte()
+ Using pinned As New PinnedBuffer(Of Byte)(SizeOf(GetType(T)))
+ StructureToPtr(obj, pinned.DangerousGetHandle(), fDeleteOld:=False)
+ Return pinned.Target
+ End Using
+ End Function
+
+
+ Public Shared Function Deserialize(Of T)(buffer As Byte(), free As Boolean, checkinput As Boolean) As T
+ If checkinput AndAlso
+ (buffer Is Nothing OrElse buffer.Length < SizeOf(GetType(T))) Then
+
+ Throw New ArgumentException("Invalid input buffer", NameOf(buffer))
+ End If
+
+ Using pinned = Create(buffer)
+ Dim obj = PtrToStructure(Of T)(pinned.DangerousGetHandle())
+ If free Then
+ DestroyStructure(Of T)(pinned.DangerousGetHandle())
+ End If
+ Return obj
+ End Using
+
+ End Function
+
+#If NET40_OR_GREATER OrElse Not NETFRAMEWORK Then
+
+ Public Sub New(existing As PinnedBuffer, offset As Integer)
+ MyBase.New(ownsHandle:=True)
+
+ Initialize(existing.ByteLength)
+
+ _gchandle = GCHandle.Alloc(existing._gchandle.Target, GCHandleType.Pinned)
+
+ SetHandle(_gchandle.AddrOfPinnedObject() + existing.Offset + offset)
+
+ End Sub
+
+ '''
+ ''' Initializes a new instance with an existing object and pins memory
+ ''' position.
+ '''
+ ''' Existing object to pin in memory.
+ ''' Total number of bytes used by obj in unmanaged memory
+ ''' Byte offset into unmanaged memory where this instance should start
+
+ Public Sub New(obj As Object, toalObjectSize As Integer, byteOffset As Integer)
+ MyClass.New()
+
+ If byteOffset > toalObjectSize Then
+ Throw New ArgumentOutOfRangeException("Argument offset must be within total object size", "offset")
+ End If
+
+ Initialize(CULng(toalObjectSize - byteOffset))
+
+ _gchandle = GCHandle.Alloc(obj, GCHandleType.Pinned)
+
+ SetHandle(_gchandle.AddrOfPinnedObject() + byteOffset)
+
+ End Sub
+#End If
+
+ '''
+ ''' Initializes a new instance with an existing object and pins memory
+ ''' position.
+ '''
+ ''' Existing object to pin in memory.
+ ''' Number of bytes in unmanaged memory
+
+ Public Sub New(obj As Object, size As Integer)
+ MyClass.New()
+
+ Initialize(CULng(size))
+
+ _gchandle = GCHandle.Alloc(obj, GCHandleType.Pinned)
+
+ SetHandle(_gchandle.AddrOfPinnedObject())
+
+ End Sub
+
+
+ Protected Overrides Function ReleaseHandle() As Boolean
+ _gchandle.Free()
+ Return True
+ End Function
+
+ Public ReadOnly Property Target As Object
+
+ Get
+ Return _gchandle.Target
+ End Get
+ End Property
+
+#If NET40_OR_GREATER OrElse Not NETFRAMEWORK Then
+
+ Public Shared Operator +(existing As PinnedBuffer, offset As Integer) As PinnedBuffer
+
+ Return New PinnedBuffer(existing, offset)
+
+ End Operator
+
+ Public Shared Operator -(existing As PinnedBuffer, offset As Integer) As PinnedBuffer
+
+ Return New PinnedBuffer(existing, -offset)
+
+ End Operator
+
+#End If
+
+
+ Public Overrides Function ToString() As String
+
+ If _gchandle.IsAllocated Then
+ Return _gchandle.Target.ToString()
+ Else
+ Return "{Unallocated}"
+ End If
+
+ End Function
+
+ End Class
+
+ '''
+ ''' Pins a managed string for unmanaged use.
+ '''
+
+
+
+ Public Class PinnedString
+ Inherits PinnedBuffer
+
+ '''
+ ''' Initializes a new instance with an existing managed string and pins memory
+ ''' position.
+ '''
+ ''' Managed string to pin in unmanaged memory.
+
+ Public Sub New(str As String)
+ MyBase.New(str, str.Length << 1)
+
+ End Sub
+
+ '''
+ ''' Initializes a new instance with a new managed string and pins memory
+ ''' position.
+ '''
+ ''' Size in characters of managed string to pin in unmanaged memory.
+
+ Public Sub New(count As Integer)
+ MyBase.New(New String(New Char, count), count << 1)
+
+ End Sub
+
+ '''
+ ''' Returns managed object pinned by this instance.
+ '''
+ Public Overloads ReadOnly Property Target As String
+
+ Get
+ Return DirectCast(_gchandle.Target, String)
+ End Get
+ End Property
+
+ End Class
+
+ '''
+ ''' Pins an array of values for unmanaged use.
+ '''
+ ''' Type of elements in array.
+
+
+
+ Public Class PinnedBuffer(Of T As Structure)
+ Inherits PinnedBuffer
+
+ '''
+ ''' Initializes a new instance with an new type T array and pins memory
+ ''' position.
+ '''
+ ''' Number of items in new array.
+
+ Public Sub New(count As Integer)
+ MyBase.New(New T(count - 1) {}, SizeOf(GetType(T)) * count)
+
+ End Sub
+
+ '''
+ ''' Initializes a new instance with an existing type T array and pins memory
+ ''' position.
+ '''
+ ''' Existing object to marshal to unmanaged memory.
+
+ Public Sub New(obj As T())
+ MyBase.New(obj, Buffer.ByteLength(obj))
+
+ End Sub
+
+#If NET40_OR_GREATER OrElse Not NETFRAMEWORK Then
+ '''
+ ''' Initializes a new instance with an existing type T array and pins memory
+ ''' position.
+ '''
+ ''' Existing object to marshal to unmanaged memory.
+
+ Public Sub New(obj As T(), arrayOffset As Integer, arrayItems As Integer)
+ MyBase.New(obj, MakeTotalByteSize(obj, arrayOffset, arrayItems), (Buffer.ByteLength(obj) \ obj.Length) * arrayOffset)
+
+ End Sub
+
+ Private Shared Function MakeTotalByteSize(obj() As T, arrayOffset As Integer, arrayItems As Integer) As Integer
+
+ If arrayOffset >= obj.Length OrElse
+ arrayOffset + arrayItems > obj.Length Then
+
+ Throw New IndexOutOfRangeException("arrayOffset and arrayItems must resolve to positions within the array")
+
+ ElseIf arrayOffset + arrayItems < obj.Length Then
+
+ Return (Buffer.ByteLength(obj) \ obj.Length) * (arrayOffset + arrayItems)
+
+ Else
+
+ Return Buffer.ByteLength(obj)
+
+ End If
+
+ End Function
+#End If
+
+ '''
+ ''' Returns associated object of this instance.
+ '''
+ Public Overloads ReadOnly Property Target As T()
+
+ Get
+ Return DirectCast(_gchandle.Target, T())
+ End Get
+ End Property
+
+ End Class
+
+End Namespace
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ComInterop/ImDiskCOM.vb b/ImDiskNet/ImDiskNet/ImDisk/ComInterop/ImDiskCOM.vb
index 43724c2..4b1470d 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ComInterop/ImDiskCOM.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ComInterop/ImDiskCOM.vb
@@ -1,4 +1,12 @@
-Namespace ImDisk.ComInterop
+#Disable Warning CA1822 ' Mark members as static
+#Disable Warning CA1707 ' Identifiers should not contain underscores
+#Disable Warning CA1711 ' Identifiers should not have incorrect suffix
+#Disable Warning CA1305 ' Specify IFormatProvider
+
+Imports System.IO
+Imports System.Runtime.InteropServices
+
+Namespace ImDisk.ComInterop
@@ -264,22 +272,22 @@
Public Structure LARGE_INTEGER
- Implements IEquatable(Of LARGE_INTEGER), IEquatable(Of Int64)
+ Implements IEquatable(Of LARGE_INTEGER), IEquatable(Of Int64), IComparable(Of LARGE_INTEGER), IComparable(Of Int64)
- Public LowPart As Int32
- Public HighPart As Int32
+ Public Property LowPart As Int32
+ Public Property HighPart As Int32
Public Property QuadPart As Int64
Get
Dim bytes As New List(Of Byte)(8)
- bytes.AddRange(BitConverter.GetBytes(LowPart))
- bytes.AddRange(BitConverter.GetBytes(HighPart))
+ bytes.AddRange(BitConverter.GetBytes(_LowPart))
+ bytes.AddRange(BitConverter.GetBytes(_HighPart))
Return BitConverter.ToInt64(bytes.ToArray(), 0)
End Get
- Set(value As Int64)
- Dim bytes = BitConverter.GetBytes(value)
- LowPart = BitConverter.ToInt32(bytes, 0)
- HighPart = BitConverter.ToInt32(bytes, 4)
+ Set
+ Dim bytes = BitConverter.GetBytes(Value)
+ _LowPart = BitConverter.ToInt32(bytes, 0)
+ _HighPart = BitConverter.ToInt32(bytes, 4)
End Set
End Property
@@ -303,12 +311,62 @@
Return value.QuadPart
End Operator
- Public Overloads Function Equals(other As Int64) As Boolean Implements IEquatable(Of Int64).Equals
- Return QuadPart = other
+ Public Overloads Function Equals(other As LARGE_INTEGER) As Boolean Implements IEquatable(Of LARGE_INTEGER).Equals
+ Return _LowPart = other._LowPart AndAlso _HighPart = other._HighPart
End Function
- Public Overloads Function Equals(other As LARGE_INTEGER) As Boolean Implements IEquatable(Of LARGE_INTEGER).Equals
- Return LowPart = other.LowPart AndAlso HighPart = other.HighPart
+ Public Overrides Function Equals(obj As Object) As Boolean
+ If TypeOf obj Is IEquatable(Of LARGE_INTEGER) Then
+ Return DirectCast(obj, IEquatable(Of LARGE_INTEGER)).Equals(Me)
+ ElseIf TypeOf obj Is IEquatable(Of Int64) Then
+ Return DirectCast(obj, IEquatable(Of Int64)).Equals(QuadPart)
+ Else
+ Return False
+ End If
+ End Function
+
+ Public Shared Operator =(left As LARGE_INTEGER, right As LARGE_INTEGER) As Boolean
+ Return left.Equals(right)
+ End Operator
+
+ Public Shared Operator <>(left As LARGE_INTEGER, right As LARGE_INTEGER) As Boolean
+ Return Not left.Equals(right)
+ End Operator
+
+ Public Function ToLARGE_INTEGER() As LARGE_INTEGER
+ Return Me
+ End Function
+
+ Public Function ToInt64() As Long
+ Return Me
+ End Function
+
+ Public Function CompareTo(other As LARGE_INTEGER) As Integer Implements IComparable(Of LARGE_INTEGER).CompareTo
+ Throw New NotImplementedException()
+ End Function
+
+ Public Shared Operator <(left As LARGE_INTEGER, right As LARGE_INTEGER) As Boolean
+ Return left.CompareTo(right) < 0
+ End Operator
+
+ Public Shared Operator <=(left As LARGE_INTEGER, right As LARGE_INTEGER) As Boolean
+ Return left.CompareTo(right) <= 0
+ End Operator
+
+ Public Shared Operator >(left As LARGE_INTEGER, right As LARGE_INTEGER) As Boolean
+ Return left.CompareTo(right) > 0
+ End Operator
+
+ Public Shared Operator >=(left As LARGE_INTEGER, right As LARGE_INTEGER) As Boolean
+ Return left.CompareTo(right) >= 0
+ End Operator
+
+ Public Function CompareTo(other As Long) As Integer Implements IComparable(Of Long).CompareTo
+ Return QuadPart.CompareTo(other)
+ End Function
+
+ Public Overloads Function Equals(other As Long) As Boolean Implements IEquatable(Of Long).Equals
+ Return QuadPart.Equals(other)
End Function
End Structure
diff --git a/ImDiskNet/ImDiskNet/ImDisk/Flags.vb b/ImDiskNet/ImDiskNet/ImDisk/Flags.vb
index f209952..75b13f7 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/Flags.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/Flags.vb
@@ -1,4 +1,7 @@
-Namespace ImDisk
+#Disable Warning CA1028 ' Enum Storage should be Int32
+#Disable Warning CA1008
+
+Namespace ImDisk
'''
''' Values for ImDisk flags fields used when creating, querying or modifying virtual disks.
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ImDiskAPI.vb b/ImDiskNet/ImDiskNet/ImDisk/ImDiskAPI.vb
index 7b8aa56..02faebf 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ImDiskAPI.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ImDiskAPI.vb
@@ -1,4 +1,9 @@
-Imports System.Threading
+Imports System.Collections.ObjectModel
+Imports System.ComponentModel
+Imports System.IO
+Imports System.Runtime.InteropServices
+Imports System.Text
+Imports System.Threading
Namespace ImDisk
@@ -69,12 +74,12 @@ Namespace ImDisk
'''
''' ImDisk API behaviour flags.
'''
- Public Shared Property APIFlags As DLL.ImDiskAPIFlags
+ Public Shared Property APIFlags As UnsafeNativeMethods.ImDiskAPIFlags
Get
- Return DLL.ImDiskGetAPIFlags()
+ Return UnsafeNativeMethods.ImDiskGetAPIFlags()
End Get
- Set(value As DLL.ImDiskAPIFlags)
- DLL.ImDiskSetAPIFlags(value)
+ Set
+ UnsafeNativeMethods.ImDiskSetAPIFlags(Value)
End Set
End Property
@@ -110,7 +115,7 @@ Namespace ImDisk
Public Shared Function GetOffsetByFileExt(ImageFile As String) As Long
Dim Offset As Long
- If DLL.ImDiskGetOffsetByFileExt(ImageFile, Offset) Then
+ If UnsafeNativeMethods.ImDiskGetOffsetByFileExt(ImageFile, Offset) Then
Return Offset
Else
Return 0
@@ -118,7 +123,7 @@ Namespace ImDisk
End Function
- Private Shared Function GetStreamReaderFunction(stream As Stream) As DLL.ImDiskReadFileManagedProc
+ Private Shared Function GetStreamReaderFunction(stream As Stream) As UnsafeNativeMethods.ImDiskReadFileManagedProc
Return _
Function(_Handle As IntPtr,
@@ -149,11 +154,11 @@ Namespace ImDisk
''' parameter is in most cases 512.
''' Offset in image file where master boot record is located.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(ImageFile As String, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(ImageFile As String, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- Dim PartitionInformation As New List(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Dim PartitionInformation As New List(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- NativeFileIO.Win32Try(DLL.ImDiskGetPartitionInformationEx(ImageFile, SectorSize, Offset,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetPartitionInformationEx(ImageFile, SectorSize, Offset,
Function(data, ByRef info)
PartitionInformation.Add(info)
Return True
@@ -172,13 +177,13 @@ Namespace ImDisk
''' parameter is in most cases 512.
''' Offset in image file where master boot record is located.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(ImageFile As Stream, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(ImageFile As Stream, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
Dim StreamReader = GetStreamReaderFunction(ImageFile)
- Dim PartitionInformation As New List(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Dim PartitionInformation As New List(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- NativeFileIO.Win32Try(DLL.ImDiskGetPartitionInfoIndirectEx(Nothing, StreamReader, SectorSize, Offset,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetPartitionInfoIndirectEx(Nothing, StreamReader, SectorSize, Offset,
Function(data, ByRef info)
PartitionInformation.Add(info)
Return True
@@ -198,11 +203,11 @@ Namespace ImDisk
''' parameter is in most cases 512.
''' Offset in image file where master boot record is located.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As DLL.ImDiskReadFileManagedProc, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As UnsafeNativeMethods.ImDiskReadFileManagedProc, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- Dim PartitionInformation As New List(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Dim PartitionInformation As New List(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- NativeFileIO.Win32Try(DLL.ImDiskGetPartitionInfoIndirectEx(Handle, ReadFileProc, SectorSize, Offset,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetPartitionInfoIndirectEx(Handle, ReadFileProc, SectorSize, Offset,
Function(data, ByRef info)
PartitionInformation.Add(info)
Return True
@@ -221,7 +226,7 @@ Namespace ImDisk
''' Sector size for translating sector values to absolute byte positions. This
''' parameter is in most cases 512.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As DLL.ImDiskReadFileManagedProc, SectorSize As UInt32) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As UnsafeNativeMethods.ImDiskReadFileManagedProc, SectorSize As UInt32) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
Return GetPartitionInformation(Handle, ReadFileProc, SectorSize, 0)
@@ -236,11 +241,11 @@ Namespace ImDisk
''' parameter is in most cases 512.
''' Offset in image file where master boot record is located.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As DLL.ImDiskReadFileUnmanagedProc, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As UnsafeNativeMethods.ImDiskReadFileUnmanagedProc, SectorSize As UInt32, Offset As Long) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- Dim PartitionInformation As New List(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Dim PartitionInformation As New List(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
- NativeFileIO.Win32Try(DLL.ImDiskGetPartitionInfoIndirectEx(Handle, ReadFileProc, SectorSize, Offset,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetPartitionInfoIndirectEx(Handle, ReadFileProc, SectorSize, Offset,
Function(data, ByRef info)
PartitionInformation.Add(info)
Return True
@@ -259,7 +264,7 @@ Namespace ImDisk
''' Sector size for translating sector values to absolute byte positions. This
''' parameter is in most cases 512.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As DLL.ImDiskReadFileUnmanagedProc, SectorSize As UInt32) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(Handle As IntPtr, ReadFileProc As UnsafeNativeMethods.ImDiskReadFileUnmanagedProc, SectorSize As UInt32) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
Return GetPartitionInformation(Handle, ReadFileProc, SectorSize, 0)
@@ -272,7 +277,7 @@ Namespace ImDisk
''' Sector size for translating sector values to absolute byte positions. This
''' parameter is in most cases 512.
''' An array of PARTITION_INFORMATION structures
- Public Shared Function GetPartitionInformation(ImageFile As String, SectorSize As UInt32) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
+ Public Shared Function GetPartitionInformation(ImageFile As String, SectorSize As UInt32) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
Return GetPartitionInformation(ImageFile, SectorSize, 0)
@@ -283,8 +288,13 @@ Namespace ImDisk
''' from source sequence with valid partition definitions.
'''
''' Sequence of partition table entries
- Public Shared Function FilterDefinedPartitions(PartitionList As IEnumerable(Of NativeFileIO.Win32API.PARTITION_INFORMATION)) As ReadOnlyCollection(Of NativeFileIO.Win32API.PARTITION_INFORMATION)
- Dim DefinedPartitions As New List(Of NativeFileIO.Win32API.PARTITION_INFORMATION)(7)
+ Public Shared Function FilterDefinedPartitions(PartitionList As IEnumerable(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)) As ReadOnlyCollection(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)
+
+ If PartitionList Is Nothing Then
+ Throw New ArgumentNullException(NameOf(PartitionList))
+ End If
+
+ Dim DefinedPartitions As New List(Of NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION)(7)
For Each PartitionInfo In PartitionList
If PartitionInfo.PartitionLength <> 0 AndAlso
Not PartitionInfo.IsContainerPartition Then
@@ -303,7 +313,7 @@ Namespace ImDisk
''' Optional offset in bytes to where raw disk data begins, for use
''' with "non-raw" image files with headers before the actual disk image data.
Public Shared Function ImageContainsISOFS(Imagefile As String, Offset As Int64) As Boolean
- Dim rc = DLL.ImDiskImageContainsISOFS(Imagefile, Offset)
+ Dim rc = UnsafeNativeMethods.ImDiskImageContainsISOFS(Imagefile, Offset)
If rc Then
Return True
ElseIf Marshal.GetLastWin32Error() = 0 Then
@@ -320,7 +330,7 @@ Namespace ImDisk
''' Optional offset in bytes to where raw disk data begins, for use
''' with "non-raw" image files with headers before the actual disk image data.
Public Shared Function ImageContainsISOFS(Imagefile As Stream, Offset As Int64) As Boolean
- Dim rc = DLL.ImDiskImageContainsISOFSIndirect(Nothing, GetStreamReaderFunction(Imagefile), Offset)
+ Dim rc = UnsafeNativeMethods.ImDiskImageContainsISOFSIndirect(Nothing, GetStreamReaderFunction(Imagefile), Offset)
If rc Then
Return True
ElseIf Marshal.GetLastWin32Error() = 0 Then
@@ -345,9 +355,9 @@ Namespace ImDisk
''' single volume.
''' A DISK_GEOMETRY structure that receives information about formatted geometry.
''' This function zeroes the Cylinders member.
- Public Shared Function GetFormattedGeometry(Imagefile As String, Offset As Int64) As NativeFileIO.Win32API.DISK_GEOMETRY
- Dim DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY
- NativeFileIO.Win32Try(DLL.ImDiskGetFormattedGeometry(Imagefile, Offset, DiskGeometry))
+ Public Shared Function GetFormattedGeometry(Imagefile As String, Offset As Int64) As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
+ Dim DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetFormattedGeometry(Imagefile, Offset, DiskGeometry))
Return DiskGeometry
End Function
@@ -365,9 +375,9 @@ Namespace ImDisk
''' single volume.
''' A DISK_GEOMETRY structure that receives information about formatted geometry.
''' This function zeroes the Cylinders member.
- Public Shared Function GetFormattedGeometry(Imagefile As Stream, Offset As Int64) As NativeFileIO.Win32API.DISK_GEOMETRY
- Dim DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY
- NativeFileIO.Win32Try(DLL.ImDiskGetFormattedGeometryIndirect(Nothing, GetStreamReaderFunction(Imagefile), Offset, DiskGeometry))
+ Public Shared Function GetFormattedGeometry(Imagefile As Stream, Offset As Int64) As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
+ Dim DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetFormattedGeometryIndirect(Nothing, GetStreamReaderFunction(Imagefile), Offset, DiskGeometry))
Return DiskGeometry
End Function
@@ -418,7 +428,7 @@ Namespace ImDisk
'''
Public Shared Sub LoadDriver()
- NativeFileIO.Win32Try(DLL.ImDiskStartService("ImDisk"))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskStartService("ImDisk"))
End Sub
@@ -430,7 +440,7 @@ Namespace ImDisk
'''
Public Shared Sub LoadHelperService()
- NativeFileIO.Win32Try(DLL.ImDiskStartService("ImDskSvc"))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskStartService("ImDskSvc"))
End Sub
@@ -445,7 +455,7 @@ Namespace ImDisk
''' Target path in native format, for example \Device\ImDisk0
Public Shared Sub CreateMountPoint(Directory As String, Target As String)
- NativeFileIO.Win32Try(DLL.ImDiskCreateMountPoint(Directory, Target))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateMountPoint(Directory, Target))
End Sub
@@ -460,7 +470,7 @@ Namespace ImDisk
''' Device number of an existing ImDisk virtual disk
Public Shared Sub CreateMountPoint(Directory As String, DeviceNumber As UInt32)
- NativeFileIO.Win32Try(DLL.ImDiskCreateMountPoint(Directory, "\Device\ImDisk" & DeviceNumber))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateMountPoint(Directory, "\Device\ImDisk" & DeviceNumber))
End Sub
@@ -472,7 +482,7 @@ Namespace ImDisk
''' letter followed by a colon to remove a drive letter mount point.
Public Shared Sub RemoveMountPoint(MountPoint As String)
- NativeFileIO.Win32Try(DLL.ImDiskRemoveMountPoint(MountPoint))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskRemoveMountPoint(MountPoint))
End Sub
@@ -481,7 +491,7 @@ Namespace ImDisk
'''
Public Shared Function FindFreeDriveLetter() As Char
- Return DLL.ImDiskFindFreeDriveLetter()
+ Return UnsafeNativeMethods.ImDiskFindFreeDriveLetter()
End Function
@@ -495,7 +505,7 @@ Namespace ImDisk
For i = 0 To 1
- If DLL.ImDiskGetDeviceListEx(NativeList.Length, NativeList) Then
+ If UnsafeNativeMethods.ImDiskGetDeviceListEx(NativeList.Length, NativeList) Then
Exit For
End If
@@ -503,7 +513,7 @@ Namespace ImDisk
Select Case errorcode
- Case NativeFileIO.Win32API.ERROR_MORE_DATA
+ Case NativeFileIO.UnsafeNativeMethods.ERROR_MORE_DATA
Array.Resize(NativeList, NativeList(0) + 1)
Continue For
@@ -532,7 +542,7 @@ Namespace ImDisk
''' Optional handle to control that can display status messages during operation.
Public Shared Sub ExtendDevice(DeviceNumber As UInt32, ExtendSize As Int64, StatusControl As IntPtr)
- NativeFileIO.Win32Try(DLL.ImDiskExtendDevice(StatusControl, DeviceNumber, ExtendSize))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskExtendDevice(StatusControl, DeviceNumber, ExtendSize))
End Sub
@@ -582,14 +592,14 @@ Namespace ImDisk
MountPoint As String,
StatusControl As IntPtr)
- Dim DiskGeometry As New NativeFileIO.Win32API.DISK_GEOMETRY With {
+ Dim DiskGeometry As New NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY With {
.Cylinders = DiskSize,
.TracksPerCylinder = TracksPerCylinder,
.SectorsPerTrack = SectorsPerTrack,
.BytesPerSector = BytesPerSector
}
- NativeFileIO.Win32Try(DLL.ImDiskCreateDevice(StatusControl,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateDevice(StatusControl,
DiskGeometry,
ImageOffset,
Flags,
@@ -625,9 +635,9 @@ Namespace ImDisk
MountPoint As String,
ByRef DeviceNumber As UInt32)
- Dim DiskGeometry As New NativeFileIO.Win32API.DISK_GEOMETRY
+ Dim DiskGeometry As New NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
- NativeFileIO.Win32Try(DLL.ImDiskCreateDeviceEx(IntPtr.Zero,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateDeviceEx(IntPtr.Zero,
DeviceNumber,
DiskGeometry,
ImageOffset,
@@ -652,11 +662,11 @@ Namespace ImDisk
MountPoint As String,
ByRef DeviceNumber As UInt32)
- Dim DiskGeometry As New NativeFileIO.Win32API.DISK_GEOMETRY With {
+ Dim DiskGeometry As New NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY With {
.Cylinders = DiskSize
}
- NativeFileIO.Win32Try(DLL.ImDiskCreateDeviceEx(IntPtr.Zero,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateDeviceEx(IntPtr.Zero,
DeviceNumber,
DiskGeometry,
0,
@@ -703,11 +713,11 @@ Namespace ImDisk
MountPoint As String,
ByRef DeviceNumber As UInt32)
- Dim DiskGeometry As New NativeFileIO.Win32API.DISK_GEOMETRY With {
+ Dim DiskGeometry As New NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY With {
.Cylinders = DiskSize
}
- NativeFileIO.Win32Try(DLL.ImDiskCreateDeviceEx(IntPtr.Zero,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateDeviceEx(IntPtr.Zero,
DeviceNumber,
DiskGeometry,
0,
@@ -760,14 +770,14 @@ Namespace ImDisk
ByRef DeviceNumber As UInt32,
StatusControl As IntPtr)
- Dim DiskGeometry As New NativeFileIO.Win32API.DISK_GEOMETRY With {
+ Dim DiskGeometry As New NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY With {
.Cylinders = DiskSize,
.TracksPerCylinder = TracksPerCylinder,
.SectorsPerTrack = SectorsPerTrack,
.BytesPerSector = BytesPerSector
}
- NativeFileIO.Win32Try(DLL.ImDiskCreateDeviceEx(StatusControl,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskCreateDeviceEx(StatusControl,
DeviceNumber,
DiskGeometry,
ImageOffset,
@@ -795,7 +805,7 @@ Namespace ImDisk
''' Optional handle to control that can display status messages during operation.
Public Shared Sub RemoveDevice(DeviceNumber As UInt32, StatusControl As IntPtr)
- NativeFileIO.Win32Try(DLL.ImDiskRemoveDevice(StatusControl, DeviceNumber, Nothing))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskRemoveDevice(StatusControl, DeviceNumber, Nothing))
End Sub
@@ -817,9 +827,10 @@ Namespace ImDisk
Public Shared Sub RemoveDevice(MountPoint As String, StatusControl As IntPtr)
If String.IsNullOrEmpty(MountPoint) Then
- Throw New ArgumentNullException("MountPoint")
+ Throw New ArgumentNullException(NameOf(MountPoint))
End If
- NativeFileIO.Win32Try(DLL.ImDiskRemoveDevice(StatusControl, 0, MountPoint))
+
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskRemoveDevice(StatusControl, 0, MountPoint))
End Sub
@@ -829,7 +840,7 @@ Namespace ImDisk
''' Device number to remove.
Public Shared Sub ForceRemoveDevice(DeviceNumber As UInt32)
- NativeFileIO.Win32Try(DLL.ImDiskForceRemoveDevice(IntPtr.Zero, DeviceNumber))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskForceRemoveDevice(IntPtr.Zero, DeviceNumber))
End Sub
@@ -862,25 +873,26 @@ Namespace ImDisk
Dim CreateDataBuffer As Byte() = Nothing
Array.Resize(CreateDataBuffer, 1096)
- NativeFileIO.Win32Try(DLL.ImDiskQueryDevice(DeviceNumber, CreateDataBuffer, CreateDataBuffer.Length))
-
- Dim CreateDataReader As New BinaryReader(New MemoryStream(CreateDataBuffer), Encoding.Unicode)
- DeviceNumber = CreateDataReader.ReadUInt32()
- Dim Dummy = CreateDataReader.ReadUInt32()
- DiskSize = CreateDataReader.ReadInt64()
- Dim MediaType = CreateDataReader.ReadInt32()
- TracksPerCylinder = CreateDataReader.ReadUInt32()
- SectorsPerTrack = CreateDataReader.ReadUInt32()
- BytesPerSector = CreateDataReader.ReadUInt32()
- ImageOffset = CreateDataReader.ReadInt64()
- Flags = CType(CreateDataReader.ReadUInt32(), ImDiskFlags)
- DriveLetter = CreateDataReader.ReadChar()
- Dim FilenameLength = CreateDataReader.ReadUInt16()
- If FilenameLength = 0 Then
- Filename = Nothing
- Else
- Filename = Encoding.Unicode.GetString(CreateDataReader.ReadBytes(FilenameLength))
- End If
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskQueryDevice(DeviceNumber, CreateDataBuffer, CreateDataBuffer.Length))
+
+ Using CreateDataReader As New BinaryReader(New MemoryStream(CreateDataBuffer), Encoding.Unicode)
+ CreateDataReader.ReadUInt32()
+ Dim Dummy = CreateDataReader.ReadUInt32()
+ DiskSize = CreateDataReader.ReadInt64()
+ Dim MediaType = CreateDataReader.ReadInt32()
+ TracksPerCylinder = CreateDataReader.ReadUInt32()
+ SectorsPerTrack = CreateDataReader.ReadUInt32()
+ BytesPerSector = CreateDataReader.ReadUInt32()
+ ImageOffset = CreateDataReader.ReadInt64()
+ Flags = CType(CreateDataReader.ReadUInt32(), ImDiskFlags)
+ DriveLetter = CreateDataReader.ReadChar()
+ Dim FilenameLength = CreateDataReader.ReadUInt16()
+ If FilenameLength = 0 Then
+ Filename = Nothing
+ Else
+ Filename = Encoding.Unicode.GetString(CreateDataReader.ReadBytes(FilenameLength))
+ End If
+ End Using
End Sub
@@ -888,10 +900,10 @@ Namespace ImDisk
''' Retrieves properties for an existing ImDisk virtual disk.
'''
''' Device number of ImDisk virtual disk to retrieve properties for.
- Public Shared Function QueryDevice(DeviceNumber As UInt32) As DLL.ImDiskCreateData
+ Public Shared Function QueryDevice(DeviceNumber As UInt32) As UnsafeNativeMethods.ImDiskCreateData
- Dim CreateDataBuffer As New DLL.ImDiskCreateData
- NativeFileIO.Win32Try(DLL.ImDiskQueryDevice(DeviceNumber, CreateDataBuffer, Marshal.SizeOf(CreateDataBuffer.GetType())))
+ Dim CreateDataBuffer As New UnsafeNativeMethods.ImDiskCreateData
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskQueryDevice(DeviceNumber, CreateDataBuffer, Marshal.SizeOf(CreateDataBuffer.GetType())))
Return CreateDataBuffer
End Function
@@ -922,7 +934,7 @@ Namespace ImDisk
Flags As ImDiskFlags,
StatusControl As IntPtr)
- NativeFileIO.Win32Try(DLL.ImDiskChangeFlags(StatusControl,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskChangeFlags(StatusControl,
DeviceNumber,
Nothing,
FlagsToChange,
@@ -956,7 +968,7 @@ Namespace ImDisk
Flags As ImDiskFlags,
StatusControl As IntPtr)
- NativeFileIO.Win32Try(DLL.ImDiskChangeFlags(StatusControl,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskChangeFlags(StatusControl,
0,
MountPoint,
FlagsToChange,
@@ -1081,11 +1093,15 @@ Namespace ImDisk
''' without any partition definitions.
''' Pointer to memory buffer of at least 512 bytes where MBR will
''' be built.
- Public Shared Sub BuildInMemoryMBR(DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
- PartitionInfo As NativeFileIO.Win32API.PARTITION_INFORMATION(),
+ Public Shared Sub BuildInMemoryMBR(DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
+ PartitionInfo As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION(),
MBR As Byte())
- NativeFileIO.Win32Try(DLL.ImDiskBuildMBR(DiskGeometry,
+ If MBR Is Nothing Then
+ Throw New ArgumentNullException(NameOf(MBR))
+ End If
+
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskBuildMBR(DiskGeometry,
PartitionInfo,
CByte(If(PartitionInfo Is Nothing, 0, PartitionInfo.Length)),
MBR,
@@ -1115,12 +1131,12 @@ Namespace ImDisk
''' This parameter can be Nothing/null to create an empty MBR with just boot code
''' without any partition definitions.
''' Memory buffer containing built MBR.
- Public Shared Function BuildInMemoryMBR(DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
- PartitionInfo As NativeFileIO.Win32API.PARTITION_INFORMATION()) As Byte()
+ Public Shared Function BuildInMemoryMBR(DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
+ PartitionInfo As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION()) As Byte()
Dim MBR(0 To 511) As Byte
- NativeFileIO.Win32Try(DLL.ImDiskBuildMBR(DiskGeometry,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskBuildMBR(DiskGeometry,
PartitionInfo,
CByte(If(PartitionInfo Is Nothing, 0, PartitionInfo.Length)),
MBR,
@@ -1139,10 +1155,10 @@ Namespace ImDisk
''' Pointer to CHS disk address in three-byte partition table
''' style format.
''' Calculated LBA disk address.
- Public Shared Function ConvertCHSToLBA(DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
+ Public Shared Function ConvertCHSToLBA(DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
CHS As Byte()) As UInteger
- Return DLL.ImDiskConvertCHSToLBA(DiskGeometry, CHS)
+ Return UnsafeNativeMethods.ImDiskConvertCHSToLBA(DiskGeometry, CHS)
End Function
@@ -1155,10 +1171,10 @@ Namespace ImDisk
''' SectorsPerTrack and TracksPerCylinder members.
''' LBA disk address.
''' Calculated CHS values expressed in an array of three bytes.
- Public Shared Function ConvertCHSToLBA(DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
+ Public Shared Function ConvertCHSToLBA(DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
LBA As UInteger) As Byte()
- Dim bytes = BitConverter.GetBytes(DLL.ImDiskConvertLBAToCHS(DiskGeometry, LBA))
+ Dim bytes = BitConverter.GetBytes(UnsafeNativeMethods.ImDiskConvertLBAToCHS(DiskGeometry, LBA))
Array.Resize(bytes, 3)
Return bytes
@@ -1169,9 +1185,9 @@ Namespace ImDisk
''' when driver is loaded).
''' ImDiskCreateData that contains device creation
''' settings to save. This structure is for example returned by QueryDevice.
- Public Shared Sub SaveRegistrySettings(CreateData As DLL.ImDiskCreateData)
+ Public Shared Sub SaveRegistrySettings(CreateData As UnsafeNativeMethods.ImDiskCreateData)
- NativeFileIO.Win32Try(DLL.ImDiskSaveRegistrySettings(CreateData))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveRegistrySettings(CreateData))
End Sub
@@ -1182,7 +1198,7 @@ Namespace ImDisk
''' Device number specified in registry settings.
Public Shared Sub RemoveRegistrySettings(DeviceNumber As UInt32)
- NativeFileIO.Win32Try(DLL.ImDiskRemoveRegistrySettings(DeviceNumber))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskRemoveRegistrySettings(DeviceNumber))
End Sub
@@ -1194,7 +1210,7 @@ Namespace ImDisk
Public Shared Function GetRegistryAutoLoadDevices() As UInt32
Dim LoadDevicesValue As UInt32
- NativeFileIO.Win32Try(DLL.ImDiskGetRegistryAutoLoadDevices(LoadDevicesValue))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetRegistryAutoLoadDevices(LoadDevicesValue))
Return LoadDevicesValue
End Function
@@ -1222,7 +1238,7 @@ Namespace ImDisk
'''
Public Shared Sub NotifyShellDriveLetter(WindowHandle As IntPtr, DriveLetterPath As String)
- NativeFileIO.Win32Try(DLL.ImDiskNotifyShellDriveLetter(WindowHandle, DriveLetterPath))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskNotifyShellDriveLetter(WindowHandle, DriveLetterPath))
End Sub
@@ -1239,7 +1255,7 @@ Namespace ImDisk
'''
Public Shared Sub NotifyRemovePending(WindowHandle As IntPtr, DriveLetter As Char)
- NativeFileIO.Win32Try(DLL.ImDiskNotifyRemovePending(WindowHandle, DriveLetter))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskNotifyRemovePending(WindowHandle, DriveLetter))
End Sub
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ImDiskControl.vb b/ImDiskNet/ImDiskNet/ImDisk/ImDiskControl.vb
index fbd49fe..cf682eb 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ImDiskControl.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ImDiskControl.vb
@@ -1,20 +1,22 @@
-Namespace ImDisk
+Imports System.Runtime.InteropServices
- '''
- ''' Represents ImDisk Virtual Disk Driver control device object.
- '''
-
- Public Class ImDiskControl
- Inherits ImDiskObject
+Namespace ImDisk
'''
- ''' Creates a new instance and opens ImDisk Virtual Disk Driver control device object.
+ ''' Represents ImDisk Virtual Disk Driver control device object.
'''
- Public Sub New()
- MyBase.New("\\?\ImDiskCtl", AccessMode:=0)
+
+ Public Class ImDiskControl
+ Inherits ImDiskObject
- End Sub
+ '''
+ ''' Creates a new instance and opens ImDisk Virtual Disk Driver control device object.
+ '''
+ Public Sub New()
+ MyBase.New("\\?\ImDiskCtl", AccessMode:=0)
- End Class
+ End Sub
+
+ End Class
End Namespace
\ No newline at end of file
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ImDiskDevice.vb b/ImDiskNet/ImDiskNet/ImDisk/ImDiskDevice.vb
index 248fc8d..259e772 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ImDiskDevice.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ImDiskDevice.vb
@@ -1,4 +1,9 @@
-Namespace ImDisk
+Imports System.ComponentModel
+Imports System.IO
+Imports System.Runtime.InteropServices
+Imports Microsoft.Win32.SafeHandles
+
+Namespace ImDisk
'''
''' Represents ImDisk Virtual Disk Driver disk device objects.
@@ -12,15 +17,15 @@
Private Shared Function OpenDeviceHandle(DeviceNumber As UInt32, AccessMode As FileAccess) As SafeFileHandle
- Dim NativeAccessMode As UInt32 = NativeFileIO.Win32API.FILE_READ_ATTRIBUTES
+ Dim NativeAccessMode As UInt32 = NativeFileIO.UnsafeNativeMethods.FILE_READ_ATTRIBUTES
If (AccessMode And FileAccess.Read) = FileAccess.Read Then
- NativeAccessMode += NativeFileIO.Win32API.GENERIC_READ
+ NativeAccessMode += NativeFileIO.UnsafeNativeMethods.GENERIC_READ
End If
If (AccessMode And FileAccess.Write) = FileAccess.Write Then
- NativeAccessMode += NativeFileIO.Win32API.GENERIC_WRITE
+ NativeAccessMode += NativeFileIO.UnsafeNativeMethods.GENERIC_WRITE
End If
- Dim Handle = DLL.ImDiskOpenDeviceByNumber(DeviceNumber, NativeAccessMode)
+ Dim Handle = UnsafeNativeMethods.ImDiskOpenDeviceByNumber(DeviceNumber, NativeAccessMode)
If Handle.IsInvalid Then
Throw New Win32Exception
End If
@@ -29,27 +34,27 @@
Throw New Win32Exception
End If
- NativeFileIO.Win32API.DeviceIoControl(Handle, NativeFileIO.Win32API.FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0UI, IntPtr.Zero, 0UI, 0UI, IntPtr.Zero)
+ NativeFileIO.UnsafeNativeMethods.DeviceIoControl(Handle, NativeFileIO.UnsafeNativeMethods.FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0UI, IntPtr.Zero, 0UI, 0UI, IntPtr.Zero)
Return Handle
End Function
Private Shared Function OpenDeviceHandle(MountPoint As String, AccessMode As FileAccess) As SafeFileHandle
- Dim NativeAccessMode As UInt32 = NativeFileIO.Win32API.FILE_READ_ATTRIBUTES
+ Dim NativeAccessMode As UInt32 = NativeFileIO.UnsafeNativeMethods.FILE_READ_ATTRIBUTES
If (AccessMode And FileAccess.Read) = FileAccess.Read Then
- NativeAccessMode += NativeFileIO.Win32API.GENERIC_READ
+ NativeAccessMode += NativeFileIO.UnsafeNativeMethods.GENERIC_READ
End If
If (AccessMode And FileAccess.Write) = FileAccess.Write Then
- NativeAccessMode += NativeFileIO.Win32API.GENERIC_WRITE
+ NativeAccessMode += NativeFileIO.UnsafeNativeMethods.GENERIC_WRITE
End If
- Dim Handle = DLL.ImDiskOpenDeviceByMountPoint(MountPoint, NativeAccessMode)
+ Dim Handle = UnsafeNativeMethods.ImDiskOpenDeviceByMountPoint(MountPoint, NativeAccessMode)
If Handle.IsInvalid Then
Throw New Win32Exception
End If
- NativeFileIO.Win32API.DeviceIoControl(Handle, NativeFileIO.Win32API.FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0UI, IntPtr.Zero, 0UI, 0UI, IntPtr.Zero)
+ NativeFileIO.UnsafeNativeMethods.DeviceIoControl(Handle, NativeFileIO.UnsafeNativeMethods.FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0UI, IntPtr.Zero, 0UI, 0UI, IntPtr.Zero)
Return Handle
End Function
@@ -80,7 +85,7 @@
Public ReadOnly Property DiskSize As Long
Get
Dim Size As Int64
- NativeFileIO.Win32Try(DLL.ImDiskGetVolumeSize(SafeFileHandle, Size))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetVolumeSize(SafeFileHandle, Size))
Return Size
End Get
End Property
@@ -117,7 +122,11 @@
Public Sub SaveImageFile(ImageFile As FileStream, BufferSize As UInt32)
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+ If ImageFile Is Nothing Then
+ Throw New ArgumentNullException(NameOf(ImageFile))
+ End If
+
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFile.SafeFileHandle,
BufferSize,
IntPtr.Zero))
@@ -134,13 +143,17 @@
Public Sub SaveImageFile(ImageFile As FileStream, BufferSize As UInt32, CancelAction As Action(Of Action(Of Boolean)))
+ If ImageFile Is Nothing Then
+ Throw New ArgumentNullException(NameOf(ImageFile))
+ End If
+
Dim CancelFlag As Integer
Dim CancelFlagHandle = GCHandle.Alloc(CancelFlag, GCHandleType.Pinned)
Try
If CancelAction IsNot Nothing Then
CancelAction(Sub(flag) CancelFlag = If(flag, 1, 0))
End If
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFile.SafeFileHandle,
BufferSize,
CancelFlagHandle.AddrOfPinnedObject()))
@@ -159,7 +172,7 @@
Public Sub SaveImageFile(ImageFile As SafeFileHandle, BufferSize As UInt32)
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFile,
BufferSize,
IntPtr.Zero))
@@ -176,13 +189,19 @@
Public Sub SaveImageFile(ImageFile As SafeFileHandle, BufferSize As UInt32, CancelAction As Action(Of Action(Of Boolean)))
+ If ImageFile Is Nothing Then
+ Throw New ArgumentNullException(NameOf(ImageFile))
+ End If
+
Dim CancelFlag As Integer
Dim CancelFlagHandle = GCHandle.Alloc(CancelFlag, GCHandleType.Pinned)
+
Try
If CancelAction IsNot Nothing Then
CancelAction(Sub(flag) CancelFlag = If(flag, 1, 0))
End If
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFile,
BufferSize,
CancelFlagHandle.AddrOfPinnedObject()))
@@ -202,9 +221,13 @@
Public Sub SaveImageFile(ImageFile As String, BufferSize As UInt32)
+ If ImageFile Is Nothing Then
+ Throw New ArgumentNullException(NameOf(ImageFile))
+ End If
+
Using ImageFileHandle = NativeFileIO.OpenFileHandle(ImageFile, FileAccess.Write, FileShare.None, FileMode.Create, Overlapped:=False)
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFileHandle,
BufferSize,
IntPtr.Zero))
@@ -223,6 +246,10 @@
Public Sub SaveImageFile(ImageFile As String, BufferSize As UInt32, CancelAction As Action(Of Action(Of Boolean)))
+ If ImageFile Is Nothing Then
+ Throw New ArgumentNullException(NameOf(ImageFile))
+ End If
+
Using ImageFileHandle = NativeFileIO.OpenFileHandle(ImageFile, FileAccess.Write, FileShare.None, FileMode.Create, Overlapped:=False)
Dim CancelFlag As Integer
@@ -231,7 +258,7 @@
If CancelAction IsNot Nothing Then
CancelAction(Sub(flag) CancelFlag = If(flag, 1, 0))
End If
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFileHandle,
BufferSize,
CancelFlagHandle.AddrOfPinnedObject()))
@@ -249,9 +276,13 @@
''' Name of file to which disk contents will be written.
Public Sub SaveImageFile(ImageFile As String)
+ If ImageFile Is Nothing Then
+ Throw New ArgumentNullException(NameOf(ImageFile))
+ End If
+
Using ImageFileHandle = NativeFileIO.OpenFileHandle(ImageFile, FileAccess.Write, FileShare.None, FileMode.Create, Overlapped:=False)
- NativeFileIO.Win32Try(DLL.ImDiskSaveImageFile(SafeFileHandle,
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskSaveImageFile(SafeFileHandle,
ImageFileHandle,
0,
IntPtr.Zero))
@@ -269,13 +300,13 @@
''' boxes etc.
''' I/O buffer size to use when reading source disk. This
''' parameter is optional, if it is zero the buffer size to use
- ''' will automatically choosen.
+ ''' will automatically chosen.
''' If this parameter is TRUE and the source device type cannot
''' be automatically determined this function will ask user for
''' a .iso suffixed image file name.
Public Sub SaveImageFileInteractive(hWnd As IntPtr, BufferSize As UInt32, IsCdRomType As Boolean)
- DLL.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, BufferSize, IsCdRomType)
+ UnsafeNativeMethods.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, BufferSize, IsCdRomType)
End Sub
@@ -292,7 +323,7 @@
Public Sub SaveImageFileInteractive(hWnd As IntPtr, IsCdRomType As Boolean)
- DLL.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, 0, IsCdRomType)
+ UnsafeNativeMethods.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, 0, IsCdRomType)
End Sub
@@ -305,11 +336,11 @@
''' boxes etc.
''' I/O buffer size to use when reading source disk. This
''' parameter is optional, if it is zero the buffer size to use
- ''' will automatically choosen.
+ ''' will automatically chosen.
Public Sub SaveImageFileInteractive(hWnd As IntPtr, BufferSize As UInt32)
- DLL.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, BufferSize, False)
+ UnsafeNativeMethods.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, BufferSize, False)
End Sub
@@ -323,7 +354,7 @@
Public Sub SaveImageFileInteractive(hWnd As IntPtr)
- DLL.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, 0, False)
+ UnsafeNativeMethods.ImDiskSaveImageFileInteractive(SafeFileHandle, hWnd, 0, False)
End Sub
@@ -338,7 +369,7 @@
Public Sub SaveImageFileInteractive(IsCdRomType As Boolean)
- DLL.ImDiskSaveImageFileInteractive(SafeFileHandle, IntPtr.Zero, 0, IsCdRomType)
+ UnsafeNativeMethods.ImDiskSaveImageFileInteractive(SafeFileHandle, IntPtr.Zero, 0, IsCdRomType)
End Sub
@@ -350,7 +381,7 @@
Public Sub SaveImageFileInteractive()
- DLL.ImDiskSaveImageFileInteractive(SafeFileHandle, IntPtr.Zero, 0, False)
+ UnsafeNativeMethods.ImDiskSaveImageFileInteractive(SafeFileHandle, IntPtr.Zero, 0, False)
End Sub
@@ -359,7 +390,7 @@
'''
Public Overloads Sub ForceRemoveDevice()
- NativeFileIO.Win32Try(DLL.ImDiskForceRemoveDevice(SafeFileHandle, 0))
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskForceRemoveDevice(SafeFileHandle, 0))
End Sub
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ImDiskDeviceStream.vb b/ImDiskNet/ImDiskNet/ImDisk/ImDiskDeviceStream.vb
index 1f89487..330c0d9 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ImDiskDeviceStream.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ImDiskDeviceStream.vb
@@ -1,43 +1,47 @@
-Namespace ImDisk
-
- '''
- ''' A FileStream derived class that represents disk devices by overriding properties and methods
- ''' where FileStream base implementation rely on file API not directly compatible with disk device
- ''' objects.
- '''
-
-
- Public Class ImDiskDeviceStream
- Inherits FileStream
+Imports System.IO
+Imports System.Runtime.InteropServices
+Imports Microsoft.Win32.SafeHandles
- '''
- ''' Initializes an ImDiskDeviceStream object for an open disk device.
- '''
- ''' Open file handle for disk device.
- ''' Access to request for stream.
- Public Sub New(SafeFileHandle As SafeFileHandle, AccessMode As FileAccess)
- MyBase.New(SafeFileHandle, AccessMode)
- End Sub
+Namespace ImDisk
'''
- ''' Retrieves raw disk size.
+ ''' A FileStream derived class that represents disk devices by overriding properties and methods
+ ''' where FileStream base implementation rely on file API not directly compatible with disk device
+ ''' objects.
'''
- Public Overrides ReadOnly Property Length As Long
- Get
- Dim Size As Int64
- NativeFileIO.Win32Try(DLL.ImDiskGetVolumeSize(SafeFileHandle, Size))
- Return Size
- End Get
- End Property
+
+
+ Public Class ImDiskDeviceStream
+ Inherits FileStream
- '''
- ''' Not implemented.
- '''
- Public Overrides Sub SetLength(value As Long)
- Throw New NotImplementedException
- End Sub
+ '''
+ ''' Initializes an ImDiskDeviceStream object for an open disk device.
+ '''
+ ''' Open file handle for disk device.
+ ''' Access to request for stream.
+ Public Sub New(SafeFileHandle As SafeFileHandle, AccessMode As FileAccess)
+ MyBase.New(SafeFileHandle, AccessMode)
+ End Sub
+
+ '''
+ ''' Retrieves raw disk size.
+ '''
+ Public Overrides ReadOnly Property Length As Long
+ Get
+ Dim Size As Int64
+ NativeFileIO.Win32Try(UnsafeNativeMethods.ImDiskGetVolumeSize(SafeFileHandle, Size))
+ Return Size
+ End Get
+ End Property
+
+ '''
+ ''' Not implemented.
+ '''
+ Public Overrides Sub SetLength(value As Long)
+ Throw New NotImplementedException
+ End Sub
- End Class
+ End Class
End Namespace
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ImDiskObject.vb b/ImDiskNet/ImDiskNet/ImDisk/ImDiskObject.vb
index 256fa72..9ded743 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ImDiskObject.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ImDiskObject.vb
@@ -1,83 +1,86 @@
-Namespace ImDisk
+Imports System.IO
+Imports System.Runtime.InteropServices
+Imports Microsoft.Win32.SafeHandles
- '''
- ''' Base class that represents ImDisk Virtual Disk Driver created device objects.
- '''
-
-
- Public Class ImDiskObject
- Implements IDisposable
-
- Public ReadOnly SafeFileHandle As SafeFileHandle
- Public ReadOnly AccessMode As FileAccess
+Namespace ImDisk
'''
- ''' Opens specified Path with CreateFile Win32 API and encapsulates the returned handle
- ''' in a new ImDiskObject.
+ ''' Base class that represents ImDisk Virtual Disk Driver created device objects.
'''
- ''' Path to pass to CreateFile API
- ''' Access mode for opening and for underlying FileStream
- Protected Sub New(Path As String, AccessMode As FileAccess)
- Me.New(NativeFileIO.OpenFileHandle(Path, AccessMode, FileShare.Read, FileMode.Open, Overlapped:=False), AccessMode)
- End Sub
+
+
+ Public Class ImDiskObject
+ Implements IDisposable
- '''
- ''' Encapsulates a handle in a new ImDiskObject.
- '''
- ''' Existing handle to use
- ''' Access mode for underlying FileStream
- Protected Sub New(Handle As SafeFileHandle, Access As FileAccess)
- SafeFileHandle = Handle
- AccessMode = Access
- End Sub
+ Public ReadOnly Property SafeFileHandle As SafeFileHandle
+ Public ReadOnly Property AccessMode As FileAccess
- '''
- ''' Checks if version of running ImDisk Virtual Disk Driver servicing this device object is compatible with this API
- ''' library. If this device object is not created by ImDisk Virtual Disk Driver this method returns False.
- '''
- Public Function CheckDriverVersion() As Boolean
+ '''
+ ''' Opens specified Path with CreateFile Win32 API and encapsulates the returned handle
+ ''' in a new ImDiskObject.
+ '''
+ ''' Path to pass to CreateFile API
+ ''' Access mode for opening and for underlying FileStream
+ Protected Sub New(Path As String, AccessMode As FileAccess)
+ Me.New(NativeFileIO.OpenFileHandle(Path, AccessMode, FileShare.Read, FileMode.Open, Overlapped:=False), AccessMode)
+ End Sub
+
+ '''
+ ''' Encapsulates a handle in a new ImDiskObject.
+ '''
+ ''' Existing handle to use
+ ''' Access mode for underlying FileStream
+ Protected Sub New(Handle As SafeFileHandle, Access As FileAccess)
+ _SafeFileHandle = Handle
+ _AccessMode = Access
+ End Sub
+
+ '''
+ ''' Checks if version of running ImDisk Virtual Disk Driver servicing this device object is compatible with this API
+ ''' library. If this device object is not created by ImDisk Virtual Disk Driver this method returns False.
+ '''
+ Public Function CheckDriverVersion() As Boolean
- Return DLL.ImDiskCheckDriverVersion(SafeFileHandle)
+ Return UnsafeNativeMethods.ImDiskCheckDriverVersion(_SafeFileHandle)
- End Function
+ End Function
#Region "IDisposable Support"
- Private disposedValue As Boolean ' To detect redundant calls
-
- ' IDisposable
- Protected Overridable Sub Dispose(disposing As Boolean)
- If Not Me.disposedValue Then
- If disposing Then
- ' TODO: dispose managed state (managed objects).
- End If
-
- ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
- If SafeFileHandle IsNot Nothing Then
- SafeFileHandle.Dispose()
- End If
-
- ' TODO: set large fields to null.
- End If
- Me.disposedValue = True
- End Sub
-
- ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
- Protected Overrides Sub Finalize()
- ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
- Dispose(False)
- MyBase.Finalize()
- End Sub
+ Private disposedValue As Boolean ' To detect redundant calls
- '''
- ''' Close device object.
- '''
- Public Sub Close() Implements IDisposable.Dispose
- ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
- Dispose(True)
- GC.SuppressFinalize(Me)
- End Sub
+ ' IDisposable
+ Protected Overridable Sub Dispose(disposing As Boolean)
+ If Not Me.disposedValue Then
+ If disposing Then
+ ' TODO: dispose managed state (managed objects).
+ _SafeFileHandle?.Dispose()
+ End If
+
+ ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
+
+ ' TODO: set large fields to null.
+ _SafeFileHandle = Nothing
+ End If
+ Me.disposedValue = True
+ End Sub
+
+ ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
+ Protected Overrides Sub Finalize()
+ ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
+ Dispose(False)
+ MyBase.Finalize()
+ End Sub
+
+ '''
+ ''' Close device object.
+ '''
+ Public Sub Close() Implements IDisposable.Dispose
+ ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
+ Dispose(True)
+ GC.SuppressFinalize(Me)
+ End Sub
#End Region
- End Class
+ End Class
End Namespace
\ No newline at end of file
diff --git a/ImDiskNet/ImDiskNet/ImDisk/ImDiskRefreshEvent.vb b/ImDiskNet/ImDiskNet/ImDisk/ImDiskRefreshEvent.vb
index 4a7be7a..2b72327 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/ImDiskRefreshEvent.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/ImDiskRefreshEvent.vb
@@ -7,7 +7,7 @@ Namespace ImDisk
Inherits WaitHandle
Public Sub New(InheritHandle As Boolean)
- SafeWaitHandle = DLL.ImDiskOpenRefreshEvent(InheritHandle)
+ SafeWaitHandle = UnsafeNativeMethods.ImDiskOpenRefreshEvent(InheritHandle)
End Sub
'''
@@ -15,7 +15,7 @@ Namespace ImDisk
''' simulates the same action done by the driver after such changes.
'''
Public Sub Notify()
- NativeFileIO.Win32Try(NativeFileIO.Win32API.PulseEvent(SafeWaitHandle))
+ NativeFileIO.Win32Try(NativeFileIO.UnsafeNativeMethods.PulseEvent(SafeWaitHandle))
End Sub
End Class
diff --git a/ImDiskNet/ImDiskNet/ImDisk/DLL.vb b/ImDiskNet/ImDiskNet/ImDisk/UnsafeNativeMethods.vb
similarity index 87%
rename from ImDiskNet/ImDiskNet/ImDisk/DLL.vb
rename to ImDiskNet/ImDiskNet/ImDisk/UnsafeNativeMethods.vb
index 872d86a..aa77df4 100644
--- a/ImDiskNet/ImDiskNet/ImDisk/DLL.vb
+++ b/ImDiskNet/ImDiskNet/ImDisk/UnsafeNativeMethods.vb
@@ -1,10 +1,15 @@
-Namespace ImDisk
+#Disable Warning CA1401 ' P/Invokes should not be visible
+#Disable Warning CA1711
+
+Imports System.Runtime.InteropServices
+Imports Microsoft.Win32.SafeHandles
+
+Namespace ImDisk
- Public Class DLL
+ Public NotInheritable Class UnsafeNativeMethods
Private Sub New()
-
End Sub
'''
@@ -64,7 +69,7 @@
ImageFileName As String,
SectorSize As UInt32,
<[In]> ByRef Offset As Int64,
- PartitionInformation As NativeFileIO.Win32API.PARTITION_INFORMATION()
+ PartitionInformation As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION()
) As Boolean
Public Declare Unicode Function ImDiskGetPartitionInformationEx _
@@ -81,7 +86,7 @@
ImageFileName As String,
SectorSize As UInt32,
<[In]> ByRef Offset As Int64,
- ByRef PartitionInformation As NativeFileIO.Win32API.PARTITION_INFORMATION
+ ByRef PartitionInformation As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION
) As Boolean
Public Delegate Function ImDiskReadFileManagedProc _
@@ -105,7 +110,7 @@
Public Delegate Function ImDiskGetPartitionInfoProc _
(
UserData As IntPtr,
- <[In]> ByRef PartitionInformation As NativeFileIO.Win32API.PARTITION_INFORMATION
+ <[In]> ByRef PartitionInformation As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION
) As Boolean
Public Declare Unicode Function ImDiskReadFileHandle _
@@ -132,7 +137,7 @@
ReadFileProc As ImDiskReadFileManagedProc,
SectorSize As UInt32,
<[In]> ByRef Offset As Int64,
- PartitionInformation As NativeFileIO.Win32API.PARTITION_INFORMATION()
+ PartitionInformation As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION()
) As Boolean
Public Declare Unicode Function ImDiskGetPartitionInfoIndirect _
@@ -150,7 +155,7 @@
ReadFileProc As ImDiskReadFileUnmanagedProc,
SectorSize As UInt32,
<[In]> ByRef Offset As Int64,
- PartitionInformation As NativeFileIO.Win32API.PARTITION_INFORMATION()
+ PartitionInformation As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION()
) As Boolean
Public Declare Unicode Function ImDiskGetPartitionInfoIndirectEx _
@@ -179,7 +184,7 @@
ReadFileProc As ImDiskReadFileManagedProc,
SectorSize As UInt32,
<[In]> ByRef Offset As Int64,
- ByRef PartitionInformation As NativeFileIO.Win32API.PARTITION_INFORMATION
+ ByRef PartitionInformation As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION
) As Boolean
Public Declare Unicode Function ImDiskImageContainsISOFS _
@@ -206,7 +211,7 @@
Lib "imdisk.cpl" (
ImageFileName As String,
<[In]> ByRef Offset As Int64,
- ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY
+ ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
) As Boolean
Public Declare Unicode Function ImDiskGetFormattedGeometryIndirect _
@@ -214,7 +219,7 @@
Handle As IntPtr,
ReadFileProc As ImDiskReadFileManagedProc,
<[In]> ByRef Offset As Int64,
- ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY
+ ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
) As Boolean
Public Declare Unicode Function ImDiskGetFormattedGeometryIndirect _
@@ -222,7 +227,7 @@
Handle As IntPtr,
ReadFileProc As ImDiskReadFileUnmanagedProc,
<[In]> ByRef Offset As Int64,
- ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY
+ ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY
) As Boolean
Public Declare Unicode Function ImDiskCreateMountPoint _
@@ -272,7 +277,7 @@
Public Declare Unicode Function ImDiskCreateDevice _
Lib "imdisk.cpl" (
hWndStatusText As IntPtr,
- ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
+ ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
ByRef ImageOffset As Int64,
Flags As UInt32,
Filename As String,
@@ -284,7 +289,7 @@
Lib "imdisk.cpl" (
hWndStatusText As IntPtr,
ByRef DeviceNumber As UInt32,
- ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
+ ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
ByRef ImageOffset As Int64,
Flags As UInt32,
Filename As String,
@@ -330,16 +335,16 @@
Public Structure ImDiskCreateData
- Public DeviceNumber As Int32
- Private _Dummy As Int32
- Public DiskSize As Int64
- Public MediaType As Int32
- Public TracksPerCylinder As UInt32
- Public SectorsPerTrack As UInt32
- Public BytesPerSector As UInt32
- Public ImageOffset As Int64
- Public Flags As ImDiskFlags
- Public DriveLetter As Char
+ Public Property DeviceNumber As Int32
+ Private ReadOnly _Dummy As Int32
+ Public Property DiskSize As Int64
+ Public Property MediaType As Int32
+ Public Property TracksPerCylinder As UInt32
+ Public Property SectorsPerTrack As UInt32
+ Public Property BytesPerSector As UInt32
+ Public Property ImageOffset As Int64
+ Public Property Flags As ImDiskFlags
+ Public Property DriveLetter As Char
Private _FilenameLength As UInt16
@@ -352,13 +357,13 @@
End If
Return _Filename
End Get
- Set(value As String)
- If value Is Nothing Then
+ Set
+ If Value Is Nothing Then
_Filename = Nothing
_FilenameLength = 0
Return
End If
- _Filename = value
+ _Filename = Value
_FilenameLength = CUShort(_Filename.Length * 2)
End Set
End Property
@@ -375,7 +380,7 @@
Lib "imdisk.cpl" (
) As Char
-
+
Public Declare Unicode Function ImDiskGetDeviceList _
Lib "imdisk.cpl" (
) As UInt64
@@ -388,8 +393,8 @@
Public Declare Unicode Function ImDiskBuildMBR _
Lib "imdisk.cpl" (
- <[In]> ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
- PartitionInfo As NativeFileIO.Win32API.PARTITION_INFORMATION(),
+ <[In]> ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
+ PartitionInfo As NativeFileIO.UnsafeNativeMethods.PARTITION_INFORMATION(),
NumberOfParts As Byte,
MBR As Byte(),
MBRSize As IntPtr
@@ -397,13 +402,13 @@
Public Declare Unicode Function ImDiskConvertCHSToLBA _
Lib "imdisk.cpl" (
- <[In]> ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
+ <[In]> ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
CHS As Byte()
) As UInt32
Public Declare Unicode Function ImDiskConvertLBAToCHS _
Lib "imdisk.cpl" (
- <[In]> ByRef DiskGeometry As NativeFileIO.Win32API.DISK_GEOMETRY,
+ <[In]> ByRef DiskGeometry As NativeFileIO.UnsafeNativeMethods.DISK_GEOMETRY,
LBA As UInt32
) As UInt32
diff --git a/ImDiskNet/ImDiskNet/ImDiskNet.vbproj b/ImDiskNet/ImDiskNet/ImDiskNet.vbproj
index 984ca47..0a9503a 100644
--- a/ImDiskNet/ImDiskNet/ImDiskNet.vbproj
+++ b/ImDiskNet/ImDiskNet/ImDiskNet.vbproj
@@ -1,158 +1,20 @@

-
+
+
+
- Debug
- AnyCPU
-
-
-
-
- {3EFCB6F8-EF7E-4F60-A0DE-BB197240FCC9}
- Library
+
LTR.IO
- ImDiskNet
- 512
- Windows
- v2.0
-
-
-
-
- true
- full
- true
- true
- ..\Debug\
- ImDiskNet.xml
-
-
- 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036
- true
- true
-
-
- pdbonly
- false
- true
- true
- ..\Release\
- ImDiskNet.xml
-
-
- 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036
- true
-
-
- On
-
-
- Binary
-
-
- On
-
-
- On
-
-
- true
-
-
+ ImDiskNet
+ ImDisk Low Level API Library
+
ImDiskNet.snk
-
-
- true
- true
- true
- bin\x86\Debug\
- ImDiskNet.xml
- true
- true
- full
- x86
- 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036
- MinimumRecommendedRules.ruleset
-
-
- true
- bin\x86\Release\
- ImDiskNet.xml
- true
- true
- pdbonly
- x86
- 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036
- MinimumRecommendedRules.ruleset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- Application.myapp
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
-
-
-
- VbMyResourcesResXFileCodeGenerator
- Resources.Designer.vb
- My.Resources
- Designer
-
-
-
-
-
- MyApplicationCodeGenerator
- Application.Designer.vb
-
-
- SettingsSingleFileGenerator
- My
- Settings.Designer.vb
-
-
-
-
-
-
\ No newline at end of file
+ false
+
+ net20;net40;netstandard2.0
+
+ true
+
+
+
+
diff --git a/ImDiskNet/ImDiskNet/My Project/AssemblyInfo.vb b/ImDiskNet/ImDiskNet/My Project/AssemblyInfo.vb
index 365e7e2..b9332a4 100644
--- a/ImDiskNet/ImDiskNet/My Project/AssemblyInfo.vb
+++ b/ImDiskNet/ImDiskNet/My Project/AssemblyInfo.vb
@@ -8,28 +8,7 @@ Imports System.Runtime.InteropServices
' Review the values of the assembly attributes
-
-
-
-
-
-
-
-
+
'The following GUID is for the ID of the typelib if this project is exposed to COM
-
-
-' Version information for an assembly consists of the following four values:
-'
-' Major Version
-' Minor Version
-' Build Number
-' Revision
-'
-' You can specify all the values or you can default the Build and Revision Numbers
-' by using the '*' as shown below:
-'
-
-
-
+
diff --git a/ImDiskNet/ImDiskNet/My Project/Settings.Designer.vb b/ImDiskNet/ImDiskNet/My Project/Settings.Designer.vb
deleted file mode 100644
index 84c0255..0000000
--- a/ImDiskNet/ImDiskNet/My Project/Settings.Designer.vb
+++ /dev/null
@@ -1,73 +0,0 @@
-'------------------------------------------------------------------------------
-'
-' This code was generated by a tool.
-' Runtime Version:4.0.30319.239
-'
-' Changes to this file may cause incorrect behavior and will be lost if
-' the code is regenerated.
-'
-'------------------------------------------------------------------------------
-
-Option Strict On
-Option Explicit On
-
-
-Namespace My
-
-
- Partial Friend NotInheritable Class MySettings
- Inherits Global.System.Configuration.ApplicationSettingsBase
-
- Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()), MySettings)
-
-#Region "My.Settings Auto-Save Functionality"
-#If _MyType = "WindowsForms" Then
- Private Shared addedHandler As Boolean
-
- Private Shared addedHandlerLockObject As New Object
-
-
- Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
- If My.Application.SaveMySettingsOnExit Then
- My.Settings.Save()
- End If
- End Sub
-#End If
-#End Region
-
- Public Shared ReadOnly Property [Default]() As MySettings
- Get
-
-#If _MyType = "WindowsForms" Then
- If Not addedHandler Then
- SyncLock addedHandlerLockObject
- If Not addedHandler Then
- AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
- addedHandler = True
- End If
- End SyncLock
- End If
-#End If
- Return defaultInstance
- End Get
- End Property
- End Class
-End Namespace
-
-Namespace My
-
-
- Friend Module MySettingsProperty
-
-
- Friend ReadOnly Property Settings() As Global.LTR.IO.My.MySettings
- Get
- Return Global.LTR.IO.My.MySettings.Default
- End Get
- End Property
- End Module
-End Namespace
diff --git a/ImDiskNet/ImDiskNet/My Project/Settings.settings b/ImDiskNet/ImDiskNet/My Project/Settings.settings
deleted file mode 100644
index 85b890b..0000000
--- a/ImDiskNet/ImDiskNet/My Project/Settings.settings
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/ImDiskNet/ImDiskNet/NativeFileIO.vb b/ImDiskNet/ImDiskNet/NativeFileIO.vb
index 12aec30..34b81da 100644
--- a/ImDiskNet/ImDiskNet/NativeFileIO.vb
+++ b/ImDiskNet/ImDiskNet/NativeFileIO.vb
@@ -1,11 +1,22 @@
-'''
-''' Provides wrappers for Win32 file API. This makes it possible to open everyting that
+#Disable Warning CA1707 ' Identifiers should not contain underscores
+#Disable Warning CA1401 ' P/Invokes should not be visible
+#Disable Warning CA2101
+
+Imports System.ComponentModel
+Imports System.IO
+Imports System.Runtime.InteropServices
+Imports Microsoft.Win32.SafeHandles
+'''
+''' Provides wrappers for Win32 file API. This makes it possible to open everything that
''' CreateFile() can open and get a FileStream based .NET wrapper around the file handle.
'''
-Public Class NativeFileIO
+Public NotInheritable Class NativeFileIO
#Region "Win32 API"
- Public Class Win32API
+ Public NotInheritable Class UnsafeNativeMethods
+
+ Private Sub New()
+ End Sub
Public Const GENERIC_READ As UInt32 = &H80000000UI
Public Const GENERIC_WRITE As UInt32 = &H40000000UI
@@ -57,6 +68,36 @@ Public Class NativeFileIO
Public Const ERROR_SERVICE_DOES_NOT_EXIST As UInt32 = 1060
Public Const ERROR_SERVICE_ALREADY_RUNNING As UInt32 = 1056
+ Public Declare Function DeviceIoControl Lib "kernel32" (
+ hDevice As SafeFileHandle,
+ dwIoControlCode As UInt32,
+ lpInBuffer As IntPtr,
+ nInBufferSize As UInt32,
+ ByRef lpOutBuffer As DISK_GEOMETRY,
+ nOutBufferSize As UInt32,
+ ByRef lpBytesReturned As UInt32,
+ lpOverlapped As IntPtr) As Boolean
+
+ Public Declare Function DeviceIoControl Lib "kernel32" (
+ hDevice As SafeFileHandle,
+ dwIoControlCode As UInt32,
+ lpInBuffer As IntPtr,
+ nInBufferSize As UInt32,
+ ByRef lpOutBuffer As Int64,
+ nOutBufferSize As UInt32,
+ ByRef lpBytesReturned As UInt32,
+ lpOverlapped As IntPtr) As Boolean
+
+ Public Declare Function DeviceIoControl Lib "kernel32" (
+ hDevice As SafeFileHandle,
+ dwIoControlCode As UInt32,
+ <[In]> ByRef lpInBuffer As DISK_GROW_PARTITION,
+ nInBufferSize As UInt32,
+ lpOutBuffer As IntPtr,
+ nOutBufferSize As UInt32,
+ ByRef lpBytesReturned As UInt32,
+ lpOverlapped As IntPtr) As Boolean
+
Structure DISK_GEOMETRY
Public Enum MEDIA_TYPE As Int32
@@ -88,11 +129,11 @@ Public Class NativeFileIO
F3_32M_512 = &H19
End Enum
- Public Cylinders As Int64
- Public MediaType As MEDIA_TYPE
- Public TracksPerCylinder As UInt32
- Public SectorsPerTrack As UInt32
- Public BytesPerSector As UInt32
+ Public Property Cylinders As Int64
+ Public Property MediaType As MEDIA_TYPE
+ Public Property TracksPerCylinder As UInt32
+ Public Property SectorsPerTrack As UInt32
+ Public Property BytesPerSector As UInt32
End Structure
@@ -117,14 +158,14 @@ Public Class NativeFileIO
PARTITION_NTFT = &H80 ' NTFT partition
End Enum
- Public StartingOffset As Int64
- Public PartitionLength As Int64
- Public HiddenSectors As UInt32
- Public PartitionNumber As UInt32
- Public PartitionType As PARTITION_TYPE
- Public BootIndicator As Byte
- Public RecognizedPartition As Byte
- Public RewritePartition As Byte
+ Public Property StartingOffset As Int64
+ Public Property PartitionLength As Int64
+ Public Property HiddenSectors As UInt32
+ Public Property PartitionNumber As UInt32
+ Public Property PartitionType As PARTITION_TYPE
+ Public Property BootIndicator As Byte
+ Public Property RecognizedPartition As Byte
+ Public Property RewritePartition As Byte
'''
''' Indicates whether this partition entry represents a Windows NT fault tolerant partition,
@@ -178,28 +219,28 @@ Public Class NativeFileIO
Public Structure DISK_GROW_PARTITION
- Public PartitionNumber As Int32
- Public BytesToGrow As Int64
+ Public Property PartitionNumber As Int32
+ Public Property BytesToGrow As Int64
End Structure
Public Structure COMMTIMEOUTS
- Public ReadIntervalTimeout As UInt32
- Public ReadTotalTimeoutMultiplier As UInt32
- Public ReadTotalTimeoutConstant As UInt32
- Public WriteTotalTimeoutMultiplier As UInt32
- Public WriteTotalTimeoutConstant As UInt32
+ Public Property ReadIntervalTimeout As UInt32
+ Public Property ReadTotalTimeoutMultiplier As UInt32
+ Public Property ReadTotalTimeoutConstant As UInt32
+ Public Property WriteTotalTimeoutMultiplier As UInt32
+ Public Property WriteTotalTimeoutConstant As UInt32
End Structure
Public Structure SERVICE_STATUS
- Public dwServiceType As Integer
- Public dwCurrentState As Integer
- Public dwControlsAccepted As Integer
- Public dwWin32ExitCode As Integer
- Public dwServiceSpecificExitCode As Integer
- Public dwCheckPoint As Integer
- Public dwWaitHint As Integer
+ Public Property dwServiceType As Integer
+ Public Property dwCurrentState As Integer
+ Public Property dwControlsAccepted As Integer
+ Public Property dwWin32ExitCode As Integer
+ Public Property dwServiceSpecificExitCode As Integer
+ Public Property dwCheckPoint As Integer
+ Public Property dwWaitHint As Integer
End Structure
@@ -232,7 +273,7 @@ Public Class NativeFileIO
''' Creates a new empty instance. This constructor is used by native to managed
''' handle marshaller.
'''
- Protected Sub New()
+ Private Sub New()
MyBase.New(ownsHandle:=True)
End Sub
@@ -249,7 +290,9 @@ Public Class NativeFileIO
Public Const ERROR_MORE_DATA As Int32 = 234L
Public Declare Auto Function OpenSCManager Lib "advapi32.dll" (
- lpMachineName As String, lpDatabaseName As String, dwDesiredAccess As Integer) As SafeServiceHandle
+ lpMachineName As String,
+ lpDatabaseName As String,
+ dwDesiredAccess As Integer) As SafeServiceHandle
Public Declare Auto Function CreateService Lib "advapi32.dll" (
hSCManager As SafeServiceHandle,
@@ -268,7 +311,7 @@ Public Class NativeFileIO
Public Declare Auto Function OpenService Lib "advapi32.dll" (
hSCManager As SafeServiceHandle,
- lpServiceName As String,
+ lpServiceName As String,
dwDesiredAccess As Integer) As SafeServiceHandle
Public Declare Auto Function ControlService Lib "advapi32.dll" (
@@ -288,10 +331,10 @@ Public Class NativeFileIO
lpServiceArgVectors As IntPtr) As Boolean
Public Declare Auto Function GetModuleHandle Lib "kernel32.dll" (
- ModuleName As String) As IntPtr
+ ModuleName As String) As IntPtr
Public Declare Auto Function LoadLibrary Lib "kernel32.dll" (
- lpFileName As String) As IntPtr
+ lpFileName As String) As IntPtr
Public Declare Auto Function FreeLibrary Lib "kernel32.dll" (
hModule As IntPtr) As Boolean
@@ -304,11 +347,11 @@ Public Class NativeFileIO
Public Declare Auto Function DefineDosDevice Lib "kernel32.dll" (
dwFlags As DEFINE_DOS_DEVICE_FLAGS,
- lpDeviceName As String,
- lpTargetPath As String) As Boolean
+ lpDeviceName As String,
+ lpTargetPath As String) As Boolean
Public Declare Unicode Function QueryDosDeviceW Lib "kernel32.dll" (
- lpDeviceName As String,
+ lpDeviceName As String,
ByRef lpTargetPath As Char(),
ucchMax As UInt32) As Boolean
@@ -321,7 +364,7 @@ Public Class NativeFileIO
<[In]> ByRef lpCommTimeouts As COMMTIMEOUTS) As Boolean
Public Declare Auto Function CreateFile Lib "kernel32" (
- lpFileName As String,
+ lpFileName As String,
dwDesiredAccess As UInt32,
dwShareMode As UInt32,
lpSecurityAttributes As IntPtr,
@@ -355,12 +398,12 @@ Public Class NativeFileIO
Public Declare Auto Function GetModuleFileName Lib "kernel32" (
hModule As IntPtr,
- lpFilename As String,
+ lpFilename As String,
nSize As Int32) As Int32
Public Declare Ansi Function GetProcAddress Lib "kernel32" (
hModule As IntPtr,
- <[In](), MarshalAs(UnmanagedType.LPStr)> lpEntryName As String) As IntPtr
+ <[In], MarshalAs(UnmanagedType.LPStr)> lpEntryName As String) As IntPtr
Public Declare Ansi Function GetProcAddress Lib "kernel32" (
hModule As IntPtr,
@@ -369,11 +412,24 @@ Public Class NativeFileIO
Public Declare Ansi Function PulseEvent Lib "kernel32" (
safeWaitHandle As SafeWaitHandle) As Boolean
+ Public Declare Auto Function RtlGenRandom Lib "advapi32" Alias "SystemFunction036" (
+ ByRef buffer As Int32,
+ length As Int32) As Byte
+
+ Public Declare Function GetFileType Lib "kernel32.dll" (handle As IntPtr) As Win32FileType
+
+ Public Declare Function GetFileType Lib "kernel32.dll" (handle As SafeFileHandle) As Win32FileType
+
+ Public Declare Function GetStdHandle Lib "kernel32.dll" (nStdHandle As StdHandle) As IntPtr
+
+ Public Declare Function GetConsoleScreenBufferInfo Lib "kernel32.dll" (hConsoleOutput As IntPtr, ByRef lpConsoleScreenBufferInfo As CONSOLE_SCREEN_BUFFER_INFO) As Boolean
+
+ Public Declare Function GetConsoleScreenBufferInfo Lib "kernel32.dll" (hConsoleOutput As SafeFileHandle, ByRef lpConsoleScreenBufferInfo As CONSOLE_SCREEN_BUFFER_INFO) As Boolean
+
End Class
#End Region
Private Sub New()
-
End Sub
'''
@@ -426,50 +482,50 @@ Public Class NativeFileIO
Overlapped As Boolean) As SafeFileHandle
If String.IsNullOrEmpty(FileName) Then
- Throw New ArgumentNullException("FileName")
+ Throw New ArgumentNullException(NameOf(FileName))
End If
- Dim NativeDesiredAccess As UInt32 = Win32API.FILE_READ_ATTRIBUTES
+ Dim NativeDesiredAccess As UInt32 = UnsafeNativeMethods.FILE_READ_ATTRIBUTES
If (DesiredAccess And FileAccess.Read) = FileAccess.Read Then
- NativeDesiredAccess = NativeDesiredAccess Or Win32API.GENERIC_READ
+ NativeDesiredAccess = NativeDesiredAccess Or UnsafeNativeMethods.GENERIC_READ
End If
If (DesiredAccess And FileAccess.Write) = FileAccess.Write Then
- NativeDesiredAccess = NativeDesiredAccess Or Win32API.GENERIC_WRITE
+ NativeDesiredAccess = NativeDesiredAccess Or UnsafeNativeMethods.GENERIC_WRITE
End If
Dim NativeShareMode As UInt32 = 0
If (ShareMode And FileShare.Read) = FileShare.Read Then
- NativeShareMode = NativeShareMode Or Win32API.FILE_SHARE_READ
+ NativeShareMode = NativeShareMode Or UnsafeNativeMethods.FILE_SHARE_READ
End If
If (ShareMode And FileShare.Write) = FileShare.Write Then
- NativeShareMode = NativeShareMode Or Win32API.FILE_SHARE_WRITE
+ NativeShareMode = NativeShareMode Or UnsafeNativeMethods.FILE_SHARE_WRITE
End If
If (ShareMode And FileShare.Delete) = FileShare.Delete Then
- NativeShareMode = NativeShareMode Or Win32API.FILE_SHARE_DELETE
+ NativeShareMode = NativeShareMode Or UnsafeNativeMethods.FILE_SHARE_DELETE
End If
- Dim NativeCreationDisposition As UInt32 = 0
+ Dim NativeCreationDisposition As UInt32
Select Case CreationDisposition
Case FileMode.Create
- NativeCreationDisposition = Win32API.CREATE_ALWAYS
+ NativeCreationDisposition = UnsafeNativeMethods.CREATE_ALWAYS
Case FileMode.CreateNew
- NativeCreationDisposition = Win32API.CREATE_NEW
+ NativeCreationDisposition = UnsafeNativeMethods.CREATE_NEW
Case FileMode.Open
- NativeCreationDisposition = Win32API.OPEN_EXISTING
+ NativeCreationDisposition = UnsafeNativeMethods.OPEN_EXISTING
Case FileMode.OpenOrCreate
- NativeCreationDisposition = Win32API.OPEN_ALWAYS
+ NativeCreationDisposition = UnsafeNativeMethods.OPEN_ALWAYS
Case FileMode.Truncate
- NativeCreationDisposition = Win32API.TRUNCATE_EXISTING
+ NativeCreationDisposition = UnsafeNativeMethods.TRUNCATE_EXISTING
Case Else
Throw New NotImplementedException
End Select
- Dim NativeFlagsAndAttributes As UInt32 = Win32API.FILE_ATTRIBUTE_NORMAL
+ Dim NativeFlagsAndAttributes As UInt32 = UnsafeNativeMethods.FILE_ATTRIBUTE_NORMAL
If Overlapped Then
- NativeFlagsAndAttributes += Win32API.FILE_FLAG_OVERLAPPED
+ NativeFlagsAndAttributes += UnsafeNativeMethods.FILE_FLAG_OVERLAPPED
End If
- Dim Handle = Win32API.CreateFile(FileName,
+ Dim Handle = UnsafeNativeMethods.CreateFile(FileName,
NativeDesiredAccess,
NativeShareMode,
IntPtr.Zero,
@@ -499,47 +555,47 @@ Public Class NativeFileIO
CreationDisposition As FileMode) As SafeFileHandle
If String.IsNullOrEmpty(FilePath) Then
- Throw New ArgumentNullException("FilePath")
+ Throw New ArgumentNullException(NameOf(FilePath))
End If
- Dim NativeDesiredAccess As UInt32 = Win32API.FILE_READ_ATTRIBUTES
+ Dim NativeDesiredAccess As UInt32 = UnsafeNativeMethods.FILE_READ_ATTRIBUTES
If (DesiredAccess And FileAccess.Read) = FileAccess.Read Then
- NativeDesiredAccess = NativeDesiredAccess Or Win32API.GENERIC_READ
+ NativeDesiredAccess = NativeDesiredAccess Or UnsafeNativeMethods.GENERIC_READ
End If
If (DesiredAccess And FileAccess.Write) = FileAccess.Write Then
- NativeDesiredAccess = NativeDesiredAccess Or Win32API.GENERIC_WRITE
+ NativeDesiredAccess = NativeDesiredAccess Or UnsafeNativeMethods.GENERIC_WRITE
End If
Dim NativeShareMode As UInt32 = 0
If (ShareMode And FileShare.Read) = FileShare.Read Then
- NativeShareMode = NativeShareMode Or Win32API.FILE_SHARE_READ
+ NativeShareMode = NativeShareMode Or UnsafeNativeMethods.FILE_SHARE_READ
End If
If (ShareMode And FileShare.Write) = FileShare.Write Then
- NativeShareMode = NativeShareMode Or Win32API.FILE_SHARE_WRITE
+ NativeShareMode = NativeShareMode Or UnsafeNativeMethods.FILE_SHARE_WRITE
End If
If (ShareMode And FileShare.Delete) = FileShare.Delete Then
- NativeShareMode = NativeShareMode Or Win32API.FILE_SHARE_DELETE
+ NativeShareMode = NativeShareMode Or UnsafeNativeMethods.FILE_SHARE_DELETE
End If
- Dim NativeCreationDisposition As UInt32 = 0
+ Dim NativeCreationDisposition As UInt32
Select Case CreationDisposition
Case FileMode.Create
- NativeCreationDisposition = Win32API.CREATE_ALWAYS
+ NativeCreationDisposition = UnsafeNativeMethods.CREATE_ALWAYS
Case FileMode.CreateNew
- NativeCreationDisposition = Win32API.CREATE_NEW
+ NativeCreationDisposition = UnsafeNativeMethods.CREATE_NEW
Case FileMode.Open
- NativeCreationDisposition = Win32API.OPEN_EXISTING
+ NativeCreationDisposition = UnsafeNativeMethods.OPEN_EXISTING
Case FileMode.OpenOrCreate
- NativeCreationDisposition = Win32API.OPEN_ALWAYS
+ NativeCreationDisposition = UnsafeNativeMethods.OPEN_ALWAYS
Case FileMode.Truncate
- NativeCreationDisposition = Win32API.TRUNCATE_EXISTING
+ NativeCreationDisposition = UnsafeNativeMethods.TRUNCATE_EXISTING
Case Else
Throw New NotImplementedException
End Select
- Dim NativeFlagsAndAttributes As UInt32 = Win32API.FILE_FLAG_BACKUP_SEMANTICS
+ Dim NativeFlagsAndAttributes As UInt32 = UnsafeNativeMethods.FILE_FLAG_BACKUP_SEMANTICS
- Dim Handle = Win32API.CreateFile(FilePath,
+ Dim Handle = UnsafeNativeMethods.CreateFile(FilePath,
NativeDesiredAccess,
NativeShareMode,
IntPtr.Zero,
@@ -645,8 +701,8 @@ Public Class NativeFileIO
Dim pinptr = GCHandle.Alloc(State, GCHandleType.Pinned)
Try
- Win32Try(Win32API.DeviceIoControl(SafeFileHandle,
- Win32API.FSCTL_SET_COMPRESSION,
+ Win32Try(UnsafeNativeMethods.DeviceIoControl(SafeFileHandle,
+ UnsafeNativeMethods.FSCTL_SET_COMPRESSION,
pinptr.AddrOfPinnedObject(),
2UI,
IntPtr.Zero,
@@ -665,66 +721,46 @@ Public Class NativeFileIO
Dim FileSize As Int64
- Win32Try(Win32API.GetFileSize(SafeFileHandle, FileSize))
+ Win32Try(UnsafeNativeMethods.GetFileSize(SafeFileHandle, FileSize))
Return FileSize
End Function
- Private Declare Function DeviceIoControl Lib "kernel32" (
- hDevice As SafeFileHandle,
- dwIoControlCode As UInt32,
- lpInBuffer As IntPtr,
- nInBufferSize As UInt32,
- ByRef lpOutBuffer As Int64,
- nOutBufferSize As UInt32,
- ByRef lpBytesReturned As UInt32,
- lpOverlapped As IntPtr) As Boolean
-
Public Shared Function GetDiskSize(SafeFileHandle As SafeFileHandle) As Int64
Dim FileSize As Int64
- Win32Try(DeviceIoControl(SafeFileHandle, Win32API.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, 0UI, FileSize, CUInt(Marshal.SizeOf(FileSize.GetType())), 0UI, IntPtr.Zero))
+ Win32Try(UnsafeNativeMethods.DeviceIoControl(SafeFileHandle, UnsafeNativeMethods.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, 0UI, FileSize, CUInt(Marshal.SizeOf(FileSize.GetType())), 0UI, IntPtr.Zero))
Return FileSize
End Function
- Private Declare Function DeviceIoControl Lib "kernel32" (
- hDevice As SafeFileHandle,
- dwIoControlCode As UInt32,
- <[In]> ByRef lpInBuffer As Win32API.DISK_GROW_PARTITION,
- nInBufferSize As UInt32,
- lpOutBuffer As IntPtr,
- nOutBufferSize As UInt32,
- ByRef lpBytesReturned As UInt32,
- lpOverlapped As IntPtr) As Boolean
-
Public Shared Sub GrowPartition(DiskHandle As SafeFileHandle, PartitionNumber As Integer, BytesToGrow As Int64)
- Dim DiskGrowPartition As Win32API.DISK_GROW_PARTITION
+ Dim DiskGrowPartition As UnsafeNativeMethods.DISK_GROW_PARTITION
DiskGrowPartition.PartitionNumber = PartitionNumber
DiskGrowPartition.BytesToGrow = BytesToGrow
- Win32Try(DeviceIoControl(DiskHandle, Win32API.IOCTL_DISK_GROW_PARTITION, DiskGrowPartition, CUInt(Marshal.SizeOf(DiskGrowPartition.GetType())), IntPtr.Zero, 0UI, 0UI, IntPtr.Zero))
+ Win32Try(UnsafeNativeMethods.DeviceIoControl(DiskHandle, UnsafeNativeMethods.IOCTL_DISK_GROW_PARTITION, DiskGrowPartition, CUInt(Marshal.SizeOf(DiskGrowPartition.GetType())), IntPtr.Zero, 0UI, 0UI, IntPtr.Zero))
End Sub
Public Shared Sub CompressFile(SafeFileHandle As SafeFileHandle)
- SetFileCompressionState(SafeFileHandle, Win32API.COMPRESSION_FORMAT_DEFAULT)
+ SetFileCompressionState(SafeFileHandle, UnsafeNativeMethods.COMPRESSION_FORMAT_DEFAULT)
End Sub
Public Shared Sub UncompressFile(SafeFileHandle As SafeFileHandle)
- SetFileCompressionState(SafeFileHandle, Win32API.COMPRESSION_FORMAT_NONE)
+ SetFileCompressionState(SafeFileHandle, UnsafeNativeMethods.COMPRESSION_FORMAT_NONE)
End Sub
Public Shared Sub AllowExtendedDASDIO(SafeFileHandle As SafeFileHandle)
- Win32Try(Win32API.DeviceIoControl(SafeFileHandle, Win32API.FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0UI, IntPtr.Zero, 0UI, 0UI, IntPtr.Zero))
+ Win32Try(UnsafeNativeMethods.DeviceIoControl(SafeFileHandle, UnsafeNativeMethods.FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0UI, IntPtr.Zero, 0UI, 0UI, IntPtr.Zero))
End Sub
@@ -791,39 +827,29 @@ Public Class NativeFileIO
''' successful lock (no other open handles) is required before attempting to dismount filesystem.
Public Shared Function DismountVolumeFilesystem(hDevice As SafeFileHandle, bForce As Boolean) As Boolean
- If Not Win32API.DeviceIoControl(hDevice, Win32API.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, Nothing, Nothing) Then
+ If Not UnsafeNativeMethods.DeviceIoControl(hDevice, UnsafeNativeMethods.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, Nothing, Nothing) Then
If Not bForce Then
Return False
End If
End If
- If Not Win32API.DeviceIoControl(hDevice, Win32API.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, Nothing, Nothing) Then
+ If Not UnsafeNativeMethods.DeviceIoControl(hDevice, UnsafeNativeMethods.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, Nothing, Nothing) Then
Return False
End If
- Return Win32API.DeviceIoControl(hDevice, Win32API.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, Nothing, Nothing)
+ Return UnsafeNativeMethods.DeviceIoControl(hDevice, UnsafeNativeMethods.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, Nothing, Nothing)
End Function
- Private Declare Function DeviceIoControl Lib "kernel32" (
- hDevice As SafeFileHandle,
- dwIoControlCode As UInt32,
- lpInBuffer As IntPtr,
- nInBufferSize As UInt32,
- ByRef lpOutBuffer As Win32API.DISK_GEOMETRY,
- nOutBufferSize As UInt32,
- ByRef lpBytesReturned As UInt32,
- lpOverlapped As IntPtr) As Boolean
-
'''
''' Retrieves disk geometry.
'''
''' Handle to device.
- Public Shared Function GetDiskGeometry(hDevice As SafeFileHandle) As Win32API.DISK_GEOMETRY
+ Public Shared Function GetDiskGeometry(hDevice As SafeFileHandle) As UnsafeNativeMethods.DISK_GEOMETRY
- Dim DiskGeometry As Win32API.DISK_GEOMETRY
+ Dim DiskGeometry As UnsafeNativeMethods.DISK_GEOMETRY
- Win32Try(DeviceIoControl(hDevice, Win32API.IOCTL_DISK_GET_DRIVE_GEOMETRY, IntPtr.Zero, 0, DiskGeometry, CUInt(Marshal.SizeOf(GetType(Win32API.DISK_GEOMETRY))), Nothing, Nothing))
+ Win32Try(UnsafeNativeMethods.DeviceIoControl(hDevice, UnsafeNativeMethods.IOCTL_DISK_GET_DRIVE_GEOMETRY, IntPtr.Zero, 0, DiskGeometry, CUInt(Marshal.SizeOf(GetType(UnsafeNativeMethods.DISK_GEOMETRY))), Nothing, Nothing))
Return DiskGeometry
@@ -831,15 +857,62 @@ Public Class NativeFileIO
Public Shared Function GetProcAddress(hModule As IntPtr, procedureName As String, delegateType As Type) As [Delegate]
- Return Marshal.GetDelegateForFunctionPointer(Win32Try(Win32API.GetProcAddress(hModule, procedureName)), delegateType)
+ Return Marshal.GetDelegateForFunctionPointer(Win32Try(UnsafeNativeMethods.GetProcAddress(hModule, procedureName)), delegateType)
End Function
Public Shared Function GetProcAddress(moduleName As String, procedureName As String, delegateType As Type) As [Delegate]
- Dim hModule = Win32Try(Win32API.LoadLibrary(moduleName))
- Return Marshal.GetDelegateForFunctionPointer(Win32Try(Win32API.GetProcAddress(hModule, procedureName)), delegateType)
+ Dim hModule = Win32Try(UnsafeNativeMethods.LoadLibrary(moduleName))
+ Return Marshal.GetDelegateForFunctionPointer(Win32Try(UnsafeNativeMethods.GetProcAddress(hModule, procedureName)), delegateType)
End Function
+ Public Enum Win32FileType As Int32
+ Unknown = &H0
+ Disk = &H1
+ Character = &H2
+ Pipe = &H3
+ Remote = &H8000
+ End Enum
+
+ Public Enum StdHandle As Int32
+ Input = -10
+ Output = -11
+ [Error] = -12
+ End Enum
+
+
+ Public Structure COORD
+ Public ReadOnly Property X As Short
+ Public ReadOnly Property Y As Short
+ End Structure
+
+
+ Public Structure SMALL_RECT
+ Public ReadOnly Property Left As Short
+ Public ReadOnly Property Top As Short
+ Public ReadOnly Property Right As Short
+ Public ReadOnly Property Bottom As Short
+ Public ReadOnly Property Width As Short
+ Get
+ Return _Right - _Left + 1S
+ End Get
+ End Property
+ Public ReadOnly Property Height As Short
+ Get
+ Return _Bottom - _Top + 1S
+ End Get
+ End Property
+ End Structure
+
+
+ Public Structure CONSOLE_SCREEN_BUFFER_INFO
+ Public ReadOnly Property dwSize As COORD
+ Public ReadOnly Property dwCursorPosition As COORD
+ Public ReadOnly Property wAttributes As Short
+ Public ReadOnly Property srWindow As SMALL_RECT
+ Public ReadOnly Property dwMaximumWindowSize As COORD
+ End Structure
+
End Class
diff --git a/ImDiskNet/ImDiskNet/Support/DisposableList.vb b/ImDiskNet/ImDiskNet/Support/DisposableList.vb
new file mode 100644
index 0000000..be90c4a
--- /dev/null
+++ b/ImDiskNet/ImDiskNet/Support/DisposableList.vb
@@ -0,0 +1,41 @@
+Imports System.Diagnostics.CodeAnalysis
+Imports System.Runtime.InteropServices
+
+'''
+''' A System.Collections.Generic.List(Of T) extended with IDisposable implementation that disposes each
+''' object in the list when the list is disposed.
+'''
+'''
+
+Public Class DisposableList(Of T As IDisposable)
+ Inherits List(Of T)
+
+ Implements IDisposable
+
+ ' IDisposable
+ Protected Overridable Sub Dispose(disposing As Boolean)
+ If disposing Then
+ ' TODO: free managed resources when explicitly called
+ For Each obj In Me
+ obj.Dispose()
+ Next
+ End If
+
+ ' TODO: free shared unmanaged resources
+ Clear()
+
+ End Sub
+
+ ' This code added by Visual Basic to correctly implement the disposable pattern.
+ Public Sub Dispose() Implements IDisposable.Dispose
+ ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
+ Dispose(True)
+ GC.SuppressFinalize(Me)
+ End Sub
+
+ Protected Overrides Sub Finalize()
+ Dispose(False)
+ MyBase.Finalize()
+ End Sub
+End Class
+
diff --git a/ImDiskNet/ImDiskNet/packages.config b/ImDiskNet/ImDiskNet/packages.config
new file mode 100644
index 0000000..f6123cd
--- /dev/null
+++ b/ImDiskNet/ImDiskNet/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImDiskNet/ImDiskNetHelpBuilder.shfbproj b/ImDiskNet/ImDiskNetHelpBuilder.shfbproj
index 9425e44..496a633 100644
--- a/ImDiskNet/ImDiskNetHelpBuilder.shfbproj
+++ b/ImDiskNet/ImDiskNetHelpBuilder.shfbproj
@@ -15,7 +15,7 @@
Documentation
Documentation
- .\Help\
+ Help\
ImDisk Virtual Disk Driver API
en-US
HtmlHelp1, MSHelpViewer, Website
@@ -23,10 +23,10 @@
None
Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, EditorBrowsableNever, NonBrowsable
-
-
-
-
+
+
+
+
diff --git a/ImDiskNet/VB6test/Form.frm b/ImDiskNet/VB6test/Form.frm
new file mode 100644
index 0000000..0e169bf
--- /dev/null
+++ b/ImDiskNet/VB6test/Form.frm
@@ -0,0 +1,190 @@
+VERSION 5.00
+Begin VB.Form Form1
+ Caption = "Form1"
+ ClientHeight = 12465
+ ClientLeft = 1650
+ ClientTop = 1545
+ ClientWidth = 6585
+ LinkTopic = "Form1"
+ ScaleHeight = 12465
+ ScaleWidth = 6585
+ Begin VB.CommandButton Command7
+ Caption = "Load driver"
+ Height = 615
+ Left = 600
+ TabIndex = 7
+ Top = 180
+ Width = 5115
+ End
+ Begin VB.CommandButton Command6
+ Caption = "Command6"
+ Height = 555
+ Left = 1680
+ TabIndex = 6
+ Top = 10140
+ Width = 3375
+ End
+ Begin VB.CommandButton Command5
+ Caption = "Read boot sector from drive"
+ Height = 495
+ Left = 540
+ TabIndex = 5
+ Top = 7920
+ Width = 5715
+ End
+ Begin VB.TextBox Text1
+ Height = 375
+ Left = 780
+ TabIndex = 4
+ Text = "Text1"
+ Top = 8580
+ Width = 5295
+ End
+ Begin VB.CommandButton Command4
+ Caption = "Load device from image file"
+ Height = 915
+ Left = 840
+ TabIndex = 3
+ Top = 6660
+ Width = 5415
+ End
+ Begin VB.CommandButton Command3
+ Caption = "Remove device"
+ Height = 735
+ Left = 1080
+ TabIndex = 2
+ Top = 4980
+ Width = 4275
+ End
+ Begin VB.CommandButton Command2
+ Caption = "Save to image file"
+ Height = 735
+ Left = 1080
+ TabIndex = 1
+ Top = 3180
+ Width = 4695
+ End
+ Begin VB.CommandButton Command1
+ Caption = "Create new device"
+ Height = 795
+ Left = 540
+ TabIndex = 0
+ Top = 1080
+ Width = 5355
+ End
+End
+Attribute VB_Name = "Form1"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = False
+Attribute VB_PredeclaredId = True
+Attribute VB_Exposed = False
+Option Explicit
+
+Dim ImDisk As New ImDiskCOM
+
+Private Sub Command1_Click()
+
+ Dim DeviceNumber As Long
+ DeviceNumber = -1
+
+ Dim DiskSize As LARGE_INTEGER
+ DiskSize.LowPart = 1440 * 2 ^ 10
+ Dim ImageOffset As LARGE_INTEGER
+
+ ImDisk.CreateDeviceEx DiskSize:=DiskSize, ImageOffset:=ImageOffset, MountPoint:="B:", DeviceNumber:=DeviceNumber, StatusControl:=Text1.hWnd
+
+ Dim Flags As ImDiskFlags
+ Dim DriveLetter As String
+ Dim Filename As String
+
+ ImDisk.QueryDevice _
+ DeviceNumber, _
+ DiskSize:=DiskSize, _
+ ImageOffset:=ImageOffset, _
+ Flags:=Flags, _
+ DriveLetter:=DriveLetter, _
+ Filename:=Filename
+
+End Sub
+
+Private Sub Command4_Click()
+
+ Dim DeviceNumber As Long
+ DeviceNumber = -1
+
+ Dim Filename As String
+ Filename = "C:\test.img"
+
+ Dim DiskSize As LARGE_INTEGER
+ Dim ImageOffset As LARGE_INTEGER
+
+ ImDisk.AutoFindOffsetAndSize Filename, ImageOffset, DiskSize
+
+ ImDisk.CreateDeviceEx DiskSize:=DiskSize, ImageOffset:=ImageOffset, Filename:=Filename, Flags:=ImDiskFlags_TypeVM, MountPoint:="B:", DeviceNumber:=DeviceNumber, StatusControl:=Text1.hWnd
+
+ Dim Flags As ImDiskFlags
+ Dim DriveLetter As String
+
+ ImDisk.QueryDevice _
+ DeviceNumber, _
+ DiskSize:=DiskSize, _
+ ImageOffset:=ImageOffset, _
+ Flags:=Flags, _
+ DriveLetter:=DriveLetter, _
+ Filename:=Filename
+
+End Sub
+
+Private Sub Command2_Click()
+
+ Dim Device As ImDiskDevice
+ Set Device = ImDisk.OpenDeviceByMountPoint("B:", FileAccess_Read)
+
+ Device.SaveImageFile "C:\test.img"
+
+ Device.Close
+
+End Sub
+
+Private Sub Command3_Click()
+
+ ImDisk.RemoveDeviceByMountPoint "B:", StatusControl:=Text1.hWnd
+
+End Sub
+
+Private Sub Command5_Click()
+
+ Dim Device As ImDiskDevice
+ Set Device = ImDisk.OpenDeviceByMountPoint("B:", FileAccess_Read)
+
+ Dim Stream As Stream
+ Set Stream = Device.GetRawDiskStream()
+
+ Text1 = ""
+ Dim i As Integer
+ For i = 0 To 511
+ Dim hexstr As String
+ hexstr = Hex(Stream.ReadByte())
+ If Len(hexstr) = 1 Then
+ hexstr = "0" & hexstr
+ End If
+ Text1 = Text1 & hexstr
+ Next
+
+ Device.Close
+
+End Sub
+
+Private Sub Command6_Click()
+
+ MkDir "C:\test"
+ ImDisk.CreateMountPointForDeviceNumber "C:\test", 0
+
+End Sub
+
+Private Sub Command7_Click()
+
+ ImDisk.LoadDriver
+ ImDisk.LoadHelperService
+
+End Sub
diff --git a/ImDiskNet/VB6test/VB6test.vbp b/ImDiskNet/VB6test/VB6test.vbp
new file mode 100644
index 0000000..b1d773f
--- /dev/null
+++ b/ImDiskNet/VB6test/VB6test.vbp
@@ -0,0 +1,33 @@
+Type=Exe
+Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#D:\WINNT\system32\stdole2.tlb#OLE Automation
+Reference=*\G{BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}#2.0#0#D:\WINNT\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb#mscorlib.dll
+Reference=*\G{8EB0AE23-5CF4-4863-A2A0-DE9F303F613A}#1.0#0#..\ImDiskNet\bin\Release\ImDiskNet.tlb#ImDiskNet
+Form=Form.frm
+Startup="Form1"
+Command32=""
+Name="Project1"
+HelpContextID="0"
+CompatibleMode="0"
+MajorVer=1
+MinorVer=0
+RevisionVer=0
+AutoIncrementVer=0
+ServerSupportFiles=0
+CompilationType=0
+OptimizationType=0
+FavorPentiumPro(tm)=0
+CodeViewDebugInfo=0
+NoAliasing=0
+BoundsCheck=0
+OverflowCheck=0
+FlPointCheck=0
+FDIVCheck=0
+UnroundedFP=0
+StartMode=0
+Unattended=0
+Retained=0
+ThreadPerObject=0
+MaxNumberOfThreads=1
+
+[MS Transaction Server]
+AutoRefresh=1
diff --git a/Makefile b/Makefile
index 97760a8..8e01d99 100644
--- a/Makefile
+++ b/Makefile
@@ -3,9 +3,10 @@
!ENDIF
!IFNDEF TIMESTAMP_WEBSERVICE
-TIMESTAMP_WEBSERVICE=http://timestamp.globalsign.com/scripts/timestamp.dll
-#TIMESTAMP_WEBSERVICE=http://timestamp.comodoca.com/authenticode
-#TIMESTAMP_WEBSERVICE=http://timestamp.verisign.com/scripts/timestamp.dll
+TIMESTAMP_WEBSERVICE=/tr "http://sha256timestamp.ws.symantec.com/sha256/timestamp"
+#TIMESTAMP_WEBSERVICE=/t "http://timestamp.globalsign.com/scripts/timestamp.dll"
+#TIMESTAMP_WEBSERVICE=/t "http://timestamp.comodoca.com/authenticode"
+#TIMESTAMP_WEBSERVICE=/t "http://timestamp.verisign.com/scripts/timestamp.dll"
!ENDIF
!IFNDEF ARCHDIR
@@ -52,7 +53,7 @@ UPLOAD_DIR=$(MAKEDIR)\dist\setup
STAMPINF_VERSION=$(IMDISK_VERSION)
-all: cli\$(ARCHDIR)\imdisk.exe svc\$(ARCHDIR)\imdsksvc.exe cpl\$(ARCHDIR)\imdisk.cpl cplcore\$(ARCHDIR)\imdisk.cpl sys\$(ARCHDIR)\imdisk.sys awealloc\$(ARCHDIR)\awealloc.sys deviotst\$(ARCHDIR)\deviotst.exe
+all: cli\$(ARCHDIR)\imdisk.exe svc\$(ARCHDIR)\imdsksvc.exe cpl\$(ARCHDIR)\imdisk.cpl cplcore\$(ARCHDIR)\imdisk.cpl sys\$(ARCHDIR)\imdisk.sys awealloc\$(ARCHDIR)\awealloc.sys deviodrv\$(ARCHDIR)\deviodrv.sys deviotst\$(ARCHDIR)\deviotst.exe
clean:
del /s *~ *.obj *.log *.wrn *.err *.mac *.o
@@ -65,7 +66,7 @@ $(DIST_DIR) $(UPLOAD_DIR):
$(DIST_DIR)\imdiskinst.exe: $(DIST_DIR)\imdisk.7z 7zSD.sfx 7zSDcfg.txt
copy /y /b 7zSD.sfx + 7zSDcfg.txt + $(DIST_DIR)\imdisk.7z $(DIST_DIR)\imdiskinst.exe
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $(DIST_DIR)\imdiskinst.exe
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $(DIST_DIR)\imdiskinst.exe
xcopy /d /y $(DIST_DIR)\imdiskinst.exe $(UPLOAD_DIR)
$(DIST_DIR)\imdisk_source.7z: $(DIST_DIR)\imdisk.7z 7zSDcfg.txt $(README_TXT_FILES) runwaitw.exe install.cmd msgboxw.exe inc\imdiskver.h devio\*.c devio\*.cpp devio\*.h devio\Makefile* uninstall_imdisk.cmd 7zSD.sfx *.sln *.props ImDiskNet\*.sln ImDiskNet\ImDiskNet\*.vb ImDiskNet\ImDiskNet\*.*proj ImDiskNet\DiscUtilsDevio\*.vb ImDiskNet\DiscUtilsDevio\*.*proj ImDiskNet\DevioNet\*.vb ImDiskNet\DevioNet\*.*proj Makefile devio\Makefile*
@@ -73,17 +74,17 @@ $(DIST_DIR)\imdisk_source.7z: $(DIST_DIR)\imdisk.7z 7zSDcfg.txt $(README_TXT_FIL
7z a -r $(DIST_DIR)\imdisk_source.7z -x!*~ -m0=PPMd 7zSDcfg.txt 7zSD.sfx $(README_TXT_FILES) *.def *.src *.ico *.c *.h *.cpp *.hpp *.cxx *.hxx *.rc *.lib *.sln *.vb *.cs *.*proj *.snk *.resx *.resources *.myapp *.settings *.props Sources dirs imdisk.inf runwaitw.exe install.cmd msgboxw.exe uninstall_imdisk.cmd Makefile
xcopy /d /y $(DIST_DIR)\imdisk_source.7z $(UPLOAD_DIR)
-$(DIST_DIR)\imdisk.7z: $(README_TXT_FILES) imdisk.inf runwaitw.exe install.cmd uninstall_imdisk.cmd msgboxw.exe cli\i386\imdisk.exe cpl\i386\imdisk.cpl cplcore\i386\imdisk.cpl svc\i386\imdsksvc.exe sys\i386\imdisk.sys awealloc\i386\awealloc.sys cli\ia64\imdisk.exe cpl\ia64\imdisk.cpl cplcore\ia64\imdisk.cpl svc\ia64\imdsksvc.exe sys\ia64\imdisk.sys awealloc\ia64\awealloc.sys cli\amd64\imdisk.exe cpl\amd64\imdisk.cpl cplcore\amd64\imdisk.cpl svc\amd64\imdsksvc.exe sys\amd64\imdisk.sys awealloc\amd64\awealloc.sys cli\arm\imdisk.exe cpl\arm\imdisk.cpl cplcore\arm\imdisk.cpl svc\arm\imdsksvc.exe sys\arm\imdisk.sys awealloc\arm\awealloc.sys cli\arm64\imdisk.exe cpl\arm64\imdisk.cpl cplcore\arm64\imdisk.cpl svc\arm64\imdsksvc.exe sys\arm64\imdisk.sys awealloc\arm64\awealloc.sys
+$(DIST_DIR)\imdisk.7z: $(README_TXT_FILES) imdisk.inf runwaitw.exe install.cmd uninstall_imdisk.cmd msgboxw.exe cli\i386\imdisk.exe cpl\i386\imdisk.cpl cplcore\i386\imdisk.cpl svc\i386\imdsksvc.exe sys\i386\imdisk.sys awealloc\i386\awealloc.sys deviodrv\i386\deviodrv.sys cli\ia64\imdisk.exe cpl\ia64\imdisk.cpl cplcore\ia64\imdisk.cpl svc\ia64\imdsksvc.exe sys\ia64\imdisk.sys awealloc\ia64\awealloc.sys deviodrv\ia64\deviodrv.sys cli\amd64\imdisk.exe cpl\amd64\imdisk.cpl cplcore\amd64\imdisk.cpl svc\amd64\imdsksvc.exe sys\amd64\imdisk.sys awealloc\amd64\awealloc.sys deviodrv\amd64\deviodrv.sys cli\arm\imdisk.exe cpl\arm\imdisk.cpl cplcore\arm\imdisk.cpl svc\arm\imdsksvc.exe sys\arm\imdisk.sys awealloc\arm\awealloc.sys deviodrv\arm\deviodrv.sys cli\arm64\imdisk.exe cpl\arm64\imdisk.cpl cplcore\arm64\imdisk.cpl svc\arm64\imdsksvc.exe sys\arm64\imdisk.sys awealloc\arm64\awealloc.sys deviodrv\arm64\deviodrv.sys
del $(DIST_DIR)\imdisk.7z
stampinf -f imdisk.inf -a NTx86,NTia64,NTamd64,NTarm,NTarm64
- 7z a $(DIST_DIR)\imdisk.7z -m0=LZMA:a=2 $(README_TXT_FILES) imdisk.inf runwaitw.exe install.cmd uninstall_imdisk.cmd msgboxw.exe cli\i386\imdisk.exe cpl\i386\imdisk.cpl cplcore\i386\imdisk.cpl svc\i386\imdsksvc.exe sys\i386\imdisk.sys awealloc\i386\awealloc.sys cli\ia64\imdisk.exe cpl\ia64\imdisk.cpl cplcore\ia64\imdisk.cpl svc\ia64\imdsksvc.exe sys\ia64\imdisk.sys awealloc\ia64\awealloc.sys cli\amd64\imdisk.exe cpl\amd64\imdisk.cpl cplcore\amd64\imdisk.cpl svc\amd64\imdsksvc.exe sys\amd64\imdisk.sys awealloc\amd64\awealloc.sys cli\arm\imdisk.exe cpl\arm\imdisk.cpl cplcore\arm\imdisk.cpl svc\arm\imdsksvc.exe sys\arm\imdisk.sys awealloc\arm\awealloc.sys cli\arm64\imdisk.exe cpl\arm64\imdisk.cpl cplcore\arm64\imdisk.cpl svc\arm64\imdsksvc.exe sys\arm64\imdisk.sys awealloc\arm64\awealloc.sys
+ 7z a $(DIST_DIR)\imdisk.7z -m0=LZMA:a=2 $(README_TXT_FILES) imdisk.inf runwaitw.exe install.cmd uninstall_imdisk.cmd msgboxw.exe cli\i386\imdisk.exe cpl\i386\imdisk.cpl cplcore\i386\imdisk.cpl svc\i386\imdsksvc.exe sys\i386\imdisk.sys awealloc\i386\awealloc.sys deviodrv\i386\deviodrv.sys cli\ia64\imdisk.exe cpl\ia64\imdisk.cpl cplcore\ia64\imdisk.cpl svc\ia64\imdsksvc.exe sys\ia64\imdisk.sys awealloc\ia64\awealloc.sys deviodrv\ia64\deviodrv.sys cli\amd64\imdisk.exe cpl\amd64\imdisk.cpl cplcore\amd64\imdisk.cpl svc\amd64\imdsksvc.exe sys\amd64\imdisk.sys awealloc\amd64\awealloc.sys deviodrv\amd64\deviodrv.sys cli\arm\imdisk.exe cpl\arm\imdisk.cpl cplcore\arm\imdisk.cpl svc\arm\imdsksvc.exe sys\arm\imdisk.sys awealloc\arm\awealloc.sys deviodrv\arm\deviodrv.sys cli\arm64\imdisk.exe cpl\arm64\imdisk.cpl cplcore\arm64\imdisk.cpl svc\arm64\imdsksvc.exe sys\arm64\imdisk.sys awealloc\arm64\awealloc.sys deviodrv\arm64\deviodrv.sys
cli\$(ARCHDIR)\imdisk.exe: cli\sources cli\*.c cli\*.rc inc\*.h cpl\$(ARCHDIR)\imdisk.lib cplcore\$(ARCHDIR)\imdisk.lib
cd cli
build
cd $(MAKEDIR)
editbin /nologo /subsystem:console,4.00 $@
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Command line tool" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $@
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Command line tool" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
cpl\$(ARCHDIR)\imdisk.lib: cpl\$(ARCHDIR)\imdisk.cpl
@@ -92,7 +93,7 @@ cpl\$(ARCHDIR)\imdisk.cpl: cpl\sources cpl\*.c cpl\*.cpp cpl\*.rc cpl\*.src cpl\
build
cd $(MAKEDIR)
editbin /nologo /subsystem:windows,4.00 $@
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Control Panel Applet" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $@
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Control Panel Applet" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
cplcore\$(ARCHDIR)\imdisk.lib: cplcore\$(ARCHDIR)\imdisk.cpl
@@ -102,29 +103,35 @@ cplcore\$(ARCHDIR)\imdisk.cpl: cplcore\sources cplcore\*.c cpl\*.c cplcore\*.cpp
build
cd $(MAKEDIR)
editbin /nologo /subsystem:windows,4.00 $@
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Core API Library" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $@
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Core API Library" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
svc\$(ARCHDIR)\imdsksvc.exe: svc\sources svc\*.cpp svc\*.rc inc\*.h inc\*.hpp
cd svc
build
cd $(MAKEDIR)
editbin /nologo /subsystem:console,4.00 $@
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Helper Service" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $@
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver Helper Service" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
-sys\$(ARCHDIR)\imdisk.sys: sys\sources sys\*.cpp sys\*.rc inc\*.h
+sys\$(ARCHDIR)\imdisk.sys: sys\sources sys\*.cpp sys\*.h sys\*.rc inc\*.h
cd sys
build
cd $(MAKEDIR)
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $@
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "ImDisk Virtual Disk Driver" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
awealloc\$(ARCHDIR)\awealloc.sys: awealloc\sources awealloc\*.c awealloc\*.rc inc\*.h
cd awealloc
build
cd $(MAKEDIR)
- $(SIGNTOOL) /n "$(COMPANYNAME)" /d "AWE Allocation Driver" /du "$(COMPANYURL)" $(CROSSCERT) /t "$(TIMESTAMP_WEBSERVICE)" $@
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "AWE Allocation Driver" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
+
+deviodrv\$(ARCHDIR)\deviodrv.sys: deviodrv\sources deviodrv\*.cpp deviodrv\*.rc deviodrv\*.h inc\*.h
+ cd deviodrv
+ build
+ cd $(MAKEDIR)
+ $(SIGNTOOL) /n "$(COMPANYNAME)" /d "DevIO Client Driver" /du "$(COMPANYURL)" $(CROSSCERT) $(TIMESTAMP_WEBSERVICE) $@
deviotst\$(ARCHDIR)\deviotst.exe: deviotst\sources deviotst\deviotst.cpp inc\*.h inc\*.hpp
cd deviotst
build
cd $(MAKEDIR)
- editbin /nologo /subsystem:console,4.00 $@
+# editbin /nologo /subsystem:console,4.00 $@
diff --git a/awealloc/awealloc.c b/awealloc/awealloc.c
index eb50db0..a6c4ee0 100644
--- a/awealloc/awealloc.c
+++ b/awealloc/awealloc.c
@@ -1,7 +1,7 @@
/*
AWE Allocation Driver for Windows 2000/XP and later.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -105,17 +105,17 @@ typedef struct _OBJECT_CONTEXT
PAGE_CONTEXT LatestPageContext;
- LONGLONG AsynchronousExchangeHit;
+ volatile LONGLONG AsynchronousExchangeHit;
KSPIN_LOCK IOLock;
- LONG ActiveReaders;
+ volatile LONG ActiveReaders;
- LONG ActiveWriters;
+ volatile LONG ActiveWriters;
- LONGLONG ReadRequestLockConflicts;
+ volatile LONGLONG ReadRequestLockConflicts;
- LONGLONG WriteRequestLockConflicts;
+ volatile LONGLONG WriteRequestLockConflicts;
BOOLEAN UseNumaNumber;
@@ -402,7 +402,9 @@ IN OUT PKIRQL LowestAssumedIrql)
(Context->ActiveReaders >= (OwnsReadLock ? 2 : 1)))
{
Context->WriteRequestLockConflicts++;
- KdPrint(("AWEAlloc: I/O write protection busy while requesting lock for writing.\n"));
+ KdPrint(("AWEAlloc: I/O write protection busy while requesting lock for writing. Active readers: %i writers: %i\n",
+ Context->ActiveReaders, Context->ActiveWriters));
+
status = STATUS_DEVICE_BUSY;
}
else
@@ -416,6 +418,10 @@ IN OUT PKIRQL LowestAssumedIrql)
}
else
{
+ KdPrint(("AWEAlloc: Thread %p acquired lock for writing. Active readers: %i writers: %i\n",
+ KeGetCurrentThread(),
+ Context->ActiveReaders, Context->ActiveWriters));
+
status = STATUS_SUCCESS;
}
}
@@ -425,7 +431,9 @@ IN OUT PKIRQL LowestAssumedIrql)
if ((Context->ActiveWriters >= 1) | (Context->ActiveReaders >= LONG_MAX))
{
Context->ReadRequestLockConflicts++;
- KdPrint(("AWEAlloc: I/O write protection busy while requesting lock for reading.\n"));
+ KdPrint(("AWEAlloc: I/O write protection busy while requesting lock for reading. Active readers: %i writers: %i\n",
+ Context->ActiveReaders, Context->ActiveWriters));
+
status = STATUS_DEVICE_BUSY;
}
else
@@ -439,6 +447,10 @@ IN OUT PKIRQL LowestAssumedIrql)
}
else
{
+ KdPrint(("AWEAlloc: Thread %p acquired lock for reading. Active readers: %i writers: %i\n",
+ KeGetCurrentThread(),
+ Context->ActiveReaders, Context->ActiveWriters));
+
status = STATUS_SUCCESS;
}
}
@@ -458,6 +470,11 @@ IN OUT PKIRQL LowestAssumedIrql)
if (ForWriteOperation)
{
Context->ActiveWriters--;
+
+ KdPrint(("AWEAlloc: Thread %p released lock for writing. Active readers: %i writers: %i\n",
+ KeGetCurrentThread(),
+ Context->ActiveReaders, Context->ActiveWriters));
+
if (Context->ActiveWriters < 0)
{
DbgPrint("AWEAlloc: I/O synchronization state corrupt.\n");
@@ -467,6 +484,11 @@ IN OUT PKIRQL LowestAssumedIrql)
if (ForReadOperation)
{
Context->ActiveReaders--;
+
+ KdPrint(("AWEAlloc: Thread %p released lock for reading. Active readers: %i writers: %i\n",
+ KeGetCurrentThread(),
+ Context->ActiveReaders, Context->ActiveWriters));
+
if (Context->ActiveReaders < 0)
{
DbgPrint("AWEAlloc: I/O synchronization state corrupt.\n");
@@ -836,6 +858,9 @@ IN PIRP Irp)
{
KdPrint(("AWEAlloc: Read request starting past EOF.\n"));
+ AWEAllocReleaseProtection(context, TRUE, FALSE,
+ &lowest_assumed_irql);
+
Irp->IoStatus.Status = STATUS_END_OF_FILE;
Irp->IoStatus.Information = 0;
@@ -937,8 +962,10 @@ IN PIRP Irp)
return STATUS_SUCCESS;
}
- if ((page_offset_this_iter + bytes_this_iter) > ALLOC_PAGE_SIZE)
+ if (((ULONGLONG)page_offset_this_iter + bytes_this_iter) > ALLOC_PAGE_SIZE)
+ {
bytes_this_iter = ALLOC_PAGE_SIZE - page_offset_this_iter;
+ }
status = AWEAllocMapPage(context, abs_offset_this_iter,
¤t_page_context, &lowest_assumed_irql);
diff --git a/awealloc/awealloc.inf b/awealloc/awealloc.inf
new file mode 100644
index 0000000..0fbc083
--- /dev/null
+++ b/awealloc/awealloc.inf
@@ -0,0 +1,54 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = awealloc.cat
+
+
+[SourceDisksNames]
+1 = "AWE Allocation Driver"
+
+
+[SourceDisksFiles.x86]
+awealloc.sys = 1, i386
+
+[SourceDisksFiles.ia64]
+awealloc.sys = 1, ia64
+
+[SourceDisksFiles.amd64]
+awealloc.sys = 1, amd64
+
+[SourceDisksFiles.arm]
+awealloc.sys = 1, arm
+
+[SourceDisksFiles.arm64]
+awealloc.sys = 1, arm64
+
+[DestinationDirs]
+AWEAllocSysFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = AWEAllocSysFiles
+
+
+[AWEAllocSysFiles]
+awealloc.sys
+
+
+[DefaultInstall.ntx86.Services]
+AddService = AWEAlloc, , AWEAllocDrv
+
+
+[AWEAllocDrv]
+DisplayName = "AWE Allocation Driver"
+StartType = 2
+ServiceType = 1
+ErrorControl = 0
+ServiceBinary = %12%\AWEAlloc.sys
diff --git a/awealloc/awealloc.props b/awealloc/awealloc.props
new file mode 100644
index 0000000..58945c9
--- /dev/null
+++ b/awealloc/awealloc.props
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ DriverEntry
+
+
+
+
\ No newline at end of file
diff --git a/awealloc/awealloc.rc b/awealloc/awealloc.rc
index e67e6bb..f2fdd20 100644
--- a/awealloc/awealloc.rc
+++ b/awealloc/awealloc.rc
@@ -10,8 +10,8 @@
//
VS_VERSION_INFO VERSIONINFO
-FILEVERSION IMDISK_RC_VERSION_FLD,22
-PRODUCTVERSION IMDISK_RC_VERSION_FLD,22
+FILEVERSION IMDISK_RC_VERSION_FLD,24
+PRODUCTVERSION IMDISK_RC_VERSION_FLD,24
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifndef DEBUG
FILEFLAGS 0
@@ -28,12 +28,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Olof Lagerkvist\0"
VALUE "FileDescription", "AWE Allocation Driver\0"
- VALUE "FileVersion", IMDISK_RC_VERSION_STR ".22\0"
+ VALUE "FileVersion", IMDISK_RC_VERSION_STR ".24\0"
VALUE "InternalName", "awealloc\0"
- VALUE "LegalCopyright", "Copyright © 2009-2018 Olof Lagerkvist.\0"
+ VALUE "LegalCopyright", "Copyright © 2009-2021 Olof Lagerkvist.\0"
VALUE "OriginalFilename", "awealloc.sys\0"
VALUE "ProductName", "imdisk\0"
- VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".22\0"
+ VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".24\0"
END
END
BLOCK "VarFileInfo"
diff --git a/awealloc/awealloc.vcxproj b/awealloc/awealloc.vcxproj
index 6db4645..53cf3d3 100644
--- a/awealloc/awealloc.vcxproj
+++ b/awealloc/awealloc.vcxproj
@@ -241,6 +241,7 @@
+
@@ -293,6 +294,7 @@
+
@@ -321,6 +323,7 @@
+
@@ -336,76 +339,76 @@
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
diff --git a/cli/cli.inf b/cli/cli.inf
new file mode 100644
index 0000000..6b9d44c
--- /dev/null
+++ b/cli/cli.inf
@@ -0,0 +1,54 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = cli.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk Virtual Disk Driver Command line tool"
+
+
+[SourceDisksFiles.x86]
+imdisk.exe = 1, i386
+
+[SourceDisksFiles.ia64]
+imdisk.exe = 1, ia64
+
+[SourceDisksFiles.amd64]
+imdisk.exe = 1, amd64
+
+[SourceDisksFiles.arm]
+imdisk.exe = 1, arm
+
+[SourceDisksFiles.arm64]
+imdisk.exe = 1, arm64
+
+[DestinationDirs]
+ImDiskExeExeFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ImDiskExeExeFiles
+
+
+[ImDiskExeExeFiles]
+imdisk.exe
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDiskExe, , ImDiskExe
+
+
+[ImDiskExe]
+DisplayName = "ImDisk Virtual Disk Driver Command line tool"
+StartType = 2
+ServiceType = 16
+ErrorControl = 0
+ServiceBinary = %11%\imdisk.exe
diff --git a/cli/cli.vcxproj b/cli/cli.vcxproj
index fdbb59b..a43689d 100644
--- a/cli/cli.vcxproj
+++ b/cli/cli.vcxproj
@@ -274,14 +274,14 @@
-
-
-
{79ee1ea9-7953-4195-ae59-317bf021eb33}
+
+
+
\ No newline at end of file
diff --git a/cli/imdisk.c b/cli/imdisk.c
index 8ec0dd7..e9dea17 100644
--- a/cli/imdisk.c
+++ b/cli/imdisk.c
@@ -2,7 +2,7 @@
Control program for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.
-Copyright (C) 2004-2018 Olof Lagerkvist.
+Copyright (C) 2004-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -90,7 +90,7 @@ void __declspec(noreturn)
ImDiskSyntaxHelp()
{
int rc = fputs
- ("Control program for the ImDisk Virtual Disk Driver.\n"
+ ("Control program for the ImDisk Virtual Disk Driver.\n"
"For copyrights and credits, type imdisk --version\n"
"\n"
"Syntax:\n"
@@ -200,8 +200,8 @@ ImDiskSyntaxHelp()
" Specifies which partition to mount when mounting a raw hard disk image\n"
" file containing a master boot record and partitions.\n"
"\n"
- " Specify number 1-4 to mount a partition from the primary partition\n"
- " table and 5-8 to mount a partition from an extended partition table.\n"
+ " Partitions are numbered in the order they are found in primary\n"
+ " partition table and then in extended partition tables.\n"
"\n"
"-S sectorsize\n"
" Sectorsize to use for the virtual disk device. Default value is 512\n"
@@ -325,6 +325,12 @@ ImDiskSyntaxHelp()
" performance or cause reads and writes to fail if underlying drivers\n"
" cannot handle I/O requests simultaneously.\n"
"\n"
+ "buf Buffered I/O. Valid for file-type virtual disks. With this flag set,\n"
+ " driver opens image file in buffered I/O mode. This is usually less\n"
+ " efficient, but it could be required to for example mount an image file\n"
+ " with smaller sector size than the volume where the image file is\n"
+ " stored.\n"
+ "\n"
"-u unit\n"
" Along with -a, request a specific unit number for the ImDisk device\n"
" instead of automatic allocation. Along with -d or -l specifies the\n"
@@ -354,7 +360,9 @@ ImDiskSyntaxHelp()
// Prints out a FormatMessage style parameterized message to specified stream.
BOOL
-ImDiskOemPrintF(FILE *Stream, LPCSTR Message, ...)
+ImDiskOemPrintF(
+ FILE* Stream,
+ LPCSTR Message, ...)
{
va_list param_list;
LPSTR lpBuf = NULL;
@@ -424,7 +432,7 @@ ImDiskCliCheckDriverVersion(HANDLE Device)
&VersionCheck, sizeof VersionCheck,
&BytesReturned, NULL))
switch (GetLastError())
- {
+ {
case ERROR_INVALID_FUNCTION:
case ERROR_NOT_SUPPORTED:
fputs("Error: Not an ImDisk device.\n", stderr);
@@ -433,7 +441,7 @@ ImDiskCliCheckDriverVersion(HANDLE Device)
default:
PrintLastError(L"Error opening device:");
return FALSE;
- }
+ }
if (BytesReturned < sizeof VersionCheck)
{
@@ -460,8 +468,9 @@ ImDiskCliCheckDriverVersion(HANDLE Device)
}
BOOL
-ImDiskCliValidateDriveLetterTarget(LPCWSTR DriveLetter,
-LPCWSTR ValidTargetPath)
+ImDiskCliValidateDriveLetterTarget(
+ LPCWSTR DriveLetter,
+ LPCWSTR ValidTargetPath)
{
WCHAR target[MAX_PATH];
@@ -481,7 +490,7 @@ LPCWSTR ValidTargetPath)
{
PrintLastError(L"Error verifying temporary drive letter:");
}
-
+
return FALSE;
}
@@ -490,9 +499,10 @@ LPCWSTR ValidTargetPath)
// a colon, and FormatOptions parameter is passed to the format.com command
// line.
int
-ImDiskCliFormatDisk(LPCWSTR DevicePath,
-WCHAR DriveLetter,
-LPCWSTR FormatOptions)
+ImDiskCliFormatDisk(
+ LPCWSTR DevicePath,
+ WCHAR DriveLetter,
+ LPCWSTR FormatOptions)
{
static const WCHAR format_mutex[] = L"ImDiskFormat";
@@ -503,7 +513,7 @@ LPCWSTR FormatOptions)
#pragma warning(suppress: 6305)
LPWSTR format_cmd = (LPWSTR)
ImDiskCliAssertNotNull(_alloca(sizeof(format_cmd_prefix) +
- sizeof(temporary_mount_point) + (wcslen(FormatOptions) << 1)));
+ sizeof(temporary_mount_point) + (wcslen(FormatOptions) << 1)));
STARTUPINFO startup_info = { sizeof(startup_info) };
PROCESS_INFORMATION process_info;
@@ -545,8 +555,8 @@ LPCWSTR FormatOptions)
if (temporary_mount_point[0] == 0)
{
fprintf
- (stderr,
- "Format failed. No free drive letters available.\n");
+ (stderr,
+ "Format failed. No free drive letters available.\n");
ReleaseMutex(hMutex);
CloseHandle(hMutex);
@@ -625,16 +635,17 @@ LPCWSTR FormatOptions)
// Creates a new virtual disk device.
int
-ImDiskCliCreateDevice(LPDWORD DeviceNumber,
-PDISK_GEOMETRY DiskGeometry,
-PLARGE_INTEGER ImageOffset,
-DWORD Flags,
-LPCWSTR FileName,
-BOOL NativePath,
-LPWSTR MountPoint,
-BOOL NumericPrint,
-LPWSTR FormatOptions,
-BOOL SaveSettings)
+ImDiskCliCreateDevice(
+ LPDWORD DeviceNumber,
+ PDISK_GEOMETRY DiskGeometry,
+ PLARGE_INTEGER ImageOffset,
+ DWORD Flags,
+ LPCWSTR FileName,
+ BOOL NativePath,
+ LPWSTR MountPoint,
+ BOOL NumericPrint,
+ LPWSTR FormatOptions,
+ BOOL SaveSettings)
{
PIMDISK_CREATE_DATA create_data;
HANDLE driver;
@@ -660,7 +671,7 @@ BOOL SaveSettings)
if (!ImDiskStartService(IMDISK_DRIVER_NAME))
switch (GetLastError())
- {
+ {
case ERROR_SERVICE_DOES_NOT_EXIST:
fputs("The ImDisk Virtual Disk Driver is not installed. "
"Please re-install ImDisk.\n", stderr);
@@ -679,7 +690,7 @@ BOOL SaveSettings)
default:
PrintLastError(L"Error loading ImDisk Virtual Disk Driver:");
return IMDISK_CLI_ERROR_DRIVER_NOT_INSTALLED;
- }
+ }
Sleep(0);
puts("The ImDisk Virtual Disk Driver was loaded into the kernel.");
@@ -692,8 +703,8 @@ BOOL SaveSettings)
}
// Physical memory allocation requires the AWEAlloc driver.
- if (((IMDISK_TYPE(Flags) == IMDISK_TYPE_FILE) |
- (IMDISK_TYPE(Flags) == 0)) &
+ if (((IMDISK_TYPE(Flags) == IMDISK_TYPE_FILE) ||
+ (IMDISK_TYPE(Flags) == 0)) &&
(IMDISK_FILE_TYPE(Flags) == IMDISK_FILE_TYPE_AWEALLOC))
{
HANDLE awealloc;
@@ -747,9 +758,9 @@ BOOL SaveSettings)
}
}
// Proxy reconnection types requires the user mode service.
- else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &
- ((IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_TCP) |
- (IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_COMM)))
+ else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &&
+ ((IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_TCP) ||
+ (IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_COMM)))
{
if (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
if (GetLastError() == ERROR_FILE_NOT_FOUND)
@@ -762,7 +773,7 @@ BOOL SaveSettings)
break;
puts
- ("The ImDisk Virtual Disk Driver Helper Service was started.");
+ ("The ImDisk Virtual Disk Driver Helper Service was started.");
}
else
{
@@ -788,7 +799,7 @@ BOOL SaveSettings)
default:
PrintLastError
- (L"Error starting ImDisk Virtual Disk Driver Helper "
+ (L"Error starting ImDisk Virtual Disk Driver Helper "
L"Service:");
}
@@ -798,7 +809,9 @@ BOOL SaveSettings)
}
if (FileName == NULL)
+ {
RtlInitUnicodeString(&file_name, NULL);
+ }
else if (NativePath)
{
if (!RtlCreateUnicodeString(&file_name, FileName))
@@ -808,21 +821,28 @@ BOOL SaveSettings)
return IMDISK_CLI_ERROR_FATAL;
}
}
- else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &
+ else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &&
(IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_SHM))
{
LPWSTR namespace_prefix;
LPWSTR prefixed_name;
HANDLE h = CreateFile(L"\\\\?\\Global", 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if ((h == INVALID_HANDLE_VALUE) &
+
+ if ((h == INVALID_HANDLE_VALUE) &&
(GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
namespace_prefix = L"\\BaseNamedObjects\\";
+ }
else
+ {
namespace_prefix = L"\\BaseNamedObjects\\Global\\";
+ }
if (h != INVALID_HANDLE_VALUE)
+ {
CloseHandle(h);
+ }
prefixed_name = (LPWSTR)
_alloca(((wcslen(namespace_prefix) + wcslen(FileName)) << 1) + 1);
@@ -862,11 +882,12 @@ BOOL SaveSettings)
puts("Creating device...");
// Check if mount point is a drive letter or junction point
- if (MountPoint != NULL)
- if ((wcslen(MountPoint) == 2) ? MountPoint[1] == ':' :
- (wcslen(MountPoint) == 3) ? wcscmp(MountPoint + 1, L":\\") == 0 :
- FALSE)
- create_data->DriveLetter = MountPoint[0];
+ if (MountPoint != NULL && MountPoint[0] != 0 &&
+ (wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
+ {
+ create_data->DriveLetter = MountPoint[0];
+ }
create_data->DeviceNumber = *DeviceNumber;
create_data->DiskGeometry = *DiskGeometry;
@@ -944,13 +965,13 @@ BOOL SaveSettings)
}
fputs
- ("Warning: The device is created without a mount point.\n",
+ ("Warning: The device is created without a mount point.\n",
stderr);
MountPoint[0] = 0;
}
}
-#ifndef _WIN64
+#ifdef _M_IX86
else if (!IMDISK_GTE_WINXP())
if (!DefineDosDevice(DDD_RAW_TARGET_PATH, MountPoint, device_path))
PrintLastError(L"Error creating mount point:");
@@ -959,13 +980,17 @@ BOOL SaveSettings)
}
if (NumericPrint)
+ {
printf("%u\n", *DeviceNumber);
+ }
else
+ {
ImDiskOemPrintF(stdout,
- "Created device %1!u!: %2!ws! -> %3!ws!",
- *DeviceNumber,
- MountPoint == NULL ? L"No mountpoint" : MountPoint,
- FileName == NULL ? L"Image in memory" : FileName);
+ "Created device %1!u!: %2!ws! -> %3!ws!",
+ *DeviceNumber,
+ MountPoint == NULL ? L"No mountpoint" : MountPoint,
+ FileName == NULL ? L"Image in memory" : FileName);
+ }
if (SaveSettings)
{
@@ -975,9 +1000,11 @@ BOOL SaveSettings)
}
if (FormatOptions != NULL)
+ {
return ImDiskCliFormatDisk(device_path,
- create_data->DriveLetter,
- FormatOptions);
+ create_data->DriveLetter,
+ FormatOptions);
+ }
return IMDISK_CLI_SUCCESS;
}
@@ -987,14 +1014,15 @@ BOOL SaveSettings)
// the virtual disk. EmergencyRemove can be set to TRUE to have the device
// immediately removed, regardless of whether device handler loop in driver is
// responsive or hung, or whether or not there are any handles open to the
-// device. Use this as a last restort to remove for example proxy backed
+// device. Use this as a last resort to remove for example proxy backed
// devices with hung proxy connections and similar.
int
-ImDiskCliRemoveDevice(DWORD DeviceNumber,
-LPCWSTR MountPoint,
-BOOL ForceDismount,
-BOOL EmergencyRemove,
-BOOL RemoveSettings)
+ImDiskCliRemoveDevice(
+ DWORD DeviceNumber,
+ LPCWSTR MountPoint,
+ BOOL ForceDismount,
+ BOOL EmergencyRemove,
+ BOOL RemoveSettings)
{
WCHAR drive_letter_mount_point[] = L" :";
DWORD dw;
@@ -1021,15 +1049,15 @@ BOOL RemoveSettings)
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- FILE_READ_ATTRIBUTES);
+ FILE_READ_ATTRIBUTES);
}
else if ((MountPoint[0] != 0) &&
((wcscmp(MountPoint + 1, L":") == 0) ||
- (wcscmp(MountPoint + 1, L":\\") == 0)))
+ (wcscmp(MountPoint + 1, L":\\") == 0)))
{
WCHAR drive_letter_path[] = L"\\\\.\\ :";
drive_letter_path[4] = MountPoint[0];
@@ -1052,17 +1080,17 @@ BOOL RemoveSettings)
if (device == INVALID_HANDLE_VALUE)
device = CreateFile(drive_letter_path,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING,
- NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING,
+ NULL);
if (device == INVALID_HANDLE_VALUE)
device = CreateFile(drive_letter_path,
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING,
- NULL);
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING,
+ NULL);
}
else
{
@@ -1071,11 +1099,11 @@ BOOL RemoveSettings)
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- GENERIC_READ);
+ GENERIC_READ);
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- FILE_READ_ATTRIBUTES);
+ FILE_READ_ATTRIBUTES);
if (device == INVALID_HANDLE_VALUE)
{
@@ -1130,7 +1158,7 @@ BOOL RemoveSettings)
create_data = (PIMDISK_CREATE_DATA)
ImDiskCliAssertNotNull(malloc(sizeof(IMDISK_CREATE_DATA) +
- (MAX_PATH << 2)));
+ (MAX_PATH << 2)));
if (!DeviceIoControl(device,
IOCTL_IMDISK_QUERY_DEVICE,
@@ -1157,7 +1185,7 @@ BOOL RemoveSettings)
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
- if ((MountPoint == NULL) & (create_data->DriveLetter != 0))
+ if ((MountPoint == NULL) && (create_data->DriveLetter != 0))
{
drive_letter_mount_point[0] = create_data->DriveLetter;
MountPoint = drive_letter_mount_point;
@@ -1188,6 +1216,7 @@ BOOL RemoveSettings)
0,
&dw,
NULL))
+ {
if (ForceDismount)
{
puts("Failed, forcing dismount...");
@@ -1215,6 +1244,7 @@ BOOL RemoveSettings)
PrintLastError(MountPoint == NULL ? L"Error" : MountPoint);
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
+ }
else
{
puts("Dismounting filesystem...");
@@ -1243,11 +1273,13 @@ BOOL RemoveSettings)
0,
&dw,
NULL))
- if (ForceDismount ? !ImDiskForceRemoveDevice(device, 0) : FALSE)
+ {
+ if (ForceDismount && !ImDiskForceRemoveDevice(device, 0))
{
PrintLastError(MountPoint == NULL ? L"Error" : MountPoint);
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
+ }
DeviceIoControl(device,
FSCTL_UNLOCK_VOLUME,
@@ -1263,7 +1295,7 @@ BOOL RemoveSettings)
if (MountPoint != NULL)
{
- puts("Removing mountpoint...");
+ printf("Removing mount point '%ws'...\n", MountPoint);
if (!ImDiskRemoveMountPoint(MountPoint))
{
@@ -1361,48 +1393,54 @@ ImDiskCliQueryStatusDriver(BOOL NumericPrint)
}
for (counter = 1; counter <= *device_list; counter++)
+ {
printf("%s%u\n",
- NumericPrint ? "" : "\\Device\\ImDisk",
- device_list[counter]);
+ NumericPrint ? "" : "\\Device\\ImDisk",
+ device_list[counter]);
+ }
HeapFree(GetProcessHeap(), 0, device_list);
return 0;
}
-/* int */
-/* ImDiskCliQueryStatusDriver(BOOL NumericPrint) */
-/* { */
-/* DWORDLONG device_list = ImDiskGetDeviceList(); */
-/* DWORD counter; */
+#if 0
+int
+ImDiskCliQueryStatusDriver(BOOL NumericPrint)
+{
+ DWORDLONG device_list = ImDiskGetDeviceList();
+ DWORD counter;
-/* if (device_list == 0) */
-/* switch (GetLastError()) */
-/* { */
-/* case NO_ERROR: */
-/* puts("No virtual disks."); */
-/* return 0; */
+ if (device_list == 0)
+ switch (GetLastError())
+ {
+ case NO_ERROR:
+ puts("No virtual disks.");
+ return 0;
-/* case ERROR_FILE_NOT_FOUND: */
-/* puts("The ImDisk Virtual Disk Driver is not loaded."); */
-/* return 0; */
+ case ERROR_FILE_NOT_FOUND:
+ puts("The ImDisk Virtual Disk Driver is not loaded.");
+ return 0;
-/* default: */
-/* PrintLastError(L"Cannot control the ImDisk Virtual Disk Driver:"); */
-/* return -1; */
-/* } */
+ default:
+ PrintLastError(L"Cannot control the ImDisk Virtual Disk Driver:");
+ return -1;
+ }
-/* for (counter = 0; device_list != 0; device_list >>= 1, counter++) */
-/* if (device_list & 1) */
-/* printf("%s%u\n", NumericPrint ? "" : "\\Device\\ImDisk", counter); */
+ for (counter = 0; device_list != 0; device_list >>= 1, counter++)
+ if (device_list & 1)
+ printf("%s%u\n", NumericPrint ? "" : "\\Device\\ImDisk", counter);
-/* return 0; */
-/* } */
+ return 0;
+}
+#endif
// Prints information about an existing virtual disk device, identified by
// either a device number or mount point.
int
-ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
+ImDiskCliQueryStatusDevice(
+ DWORD DeviceNumber,
+ LPWSTR MountPoint)
{
HANDLE device;
DWORD dw;
@@ -1451,6 +1489,7 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
}
if (device == INVALID_HANDLE_VALUE)
+ {
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
fputs("No such device.\n", stderr);
@@ -1461,6 +1500,7 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
PrintLastError(L"Error opening device:");
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
+ }
if (!ImDiskCliCheckDriverVersion(device))
{
@@ -1470,7 +1510,7 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
create_data = (PIMDISK_CREATE_DATA)
ImDiskCliAssertNotNull(malloc(sizeof(IMDISK_CREATE_DATA) +
- (MAX_PATH << 2)));
+ (MAX_PATH << 2)));
if (!DeviceIoControl(device,
IOCTL_IMDISK_QUERY_DEVICE,
@@ -1481,10 +1521,13 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
&dw, NULL))
{
PrintLastError(MountPoint);
+
ImDiskOemPrintF(stderr,
"%1!ws!: Is that drive really an ImDisk drive?",
MountPoint);
+
CloseHandle(device);
+
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
@@ -1501,28 +1544,40 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
CloseHandle(device);
if (MountPoint != NULL)
+ {
ImDiskOemPrintF(stdout,
- "Mount point: %1!ws!",
- MountPoint);
+ "Mount point: %1!ws!",
+ MountPoint);
+ }
else if (create_data->DriveLetter != 0)
+ {
ImDiskOemPrintF(stdout,
- "Drive letter: %1!wc!",
- create_data->DriveLetter);
+ "Drive letter: %1!wc!",
+ create_data->DriveLetter);
+ }
else
+ {
puts("No drive letter.");
+ }
if (create_data->FileNameLength != 0)
+ {
ImDiskOemPrintF(stdout,
- "Image file: %1!.*ws!",
- (int)(create_data->FileNameLength /
- sizeof(*create_data->FileName)),
- create_data->FileName);
+ "Image file: %1!.*ws!",
+ (int)(create_data->FileNameLength /
+ sizeof(*create_data->FileName)),
+ create_data->FileName);
+ }
else
+ {
puts("No image file.");
+ }
if (create_data->ImageOffset.QuadPart > 0)
+ {
printf("Image file offset: %I64i bytes\n",
- create_data->ImageOffset.QuadPart);
+ create_data->ImageOffset.QuadPart);
+ }
printf("Size: %I64i bytes (%.4g %s)",
create_data->DiskGeometry.Cylinders.QuadPart,
@@ -1543,8 +1598,10 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
IMDISK_FILE_TYPE(create_data->Flags) == IMDISK_FILE_TYPE_AWEALLOC ?
", Physical Memory" :
IMDISK_FILE_TYPE(create_data->Flags) == IMDISK_FILE_TYPE_PARALLEL_IO ?
- ", Parallel I/O Image File" :
- ", Queued I/O Image File",
+ ", Parallel I/O Image File" :
+ IMDISK_FILE_TYPE(create_data->Flags) == IMDISK_FILE_TYPE_BUFFERED_IO ?
+ ", Queued buffered I/O Image File" :
+ ", Queued unbuffered I/O Image File",
IMDISK_DEVICE_TYPE(create_data->Flags) ==
IMDISK_DEVICE_TYPE_CD ? ", CD-ROM" :
IMDISK_DEVICE_TYPE(create_data->Flags) ==
@@ -1562,8 +1619,11 @@ ImDiskCliQueryStatusDevice(DWORD DeviceNumber, LPWSTR MountPoint)
// number or mount point. FlagsToChange specifies which flag bits to change,
// (0=not touch, 1=set to corresponding bit value in Flags parameter).
int
-ImDiskCliChangeFlags(DWORD DeviceNumber, LPCWSTR MountPoint,
-DWORD FlagsToChange, DWORD Flags)
+ImDiskCliChangeFlags(
+ DWORD DeviceNumber,
+ LPCWSTR MountPoint,
+ DWORD FlagsToChange,
+ DWORD Flags)
{
HANDLE device;
DWORD dw;
@@ -1573,21 +1633,27 @@ DWORD FlagsToChange, DWORD Flags)
{
device = ImDiskOpenDeviceByNumber(DeviceNumber,
GENERIC_READ | GENERIC_WRITE);
+
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
+ }
}
else
{
device = ImDiskOpenDeviceByMountPoint(MountPoint,
GENERIC_READ | GENERIC_WRITE);
+
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- GENERIC_READ);
+ GENERIC_READ);
+ }
if (device == INVALID_HANDLE_VALUE)
switch (GetLastError())
- {
+ {
case ERROR_INVALID_PARAMETER:
fputs("This version of Windows only supports drive letters as "
"mount points.\n"
@@ -1611,10 +1677,11 @@ DWORD FlagsToChange, DWORD Flags)
default:
PrintLastError(MountPoint);
return IMDISK_CLI_ERROR_BAD_MOUNT_POINT;
- }
+ }
}
if (device == INVALID_HANDLE_VALUE)
+ {
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
fputs("No such device.\n", stderr);
@@ -1625,6 +1692,7 @@ DWORD FlagsToChange, DWORD Flags)
PrintLastError(L"Error opening device:");
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
+ }
if (!ImDiskCliCheckDriverVersion(device))
{
@@ -1675,6 +1743,7 @@ DWORD FlagsToChange, DWORD Flags)
device_flags.FlagsToChange = FlagsToChange;
device_flags.FlagValues = Flags;
+
if (!DeviceIoControl(device,
IOCTL_IMDISK_SET_DEVICE_FLAGS,
&device_flags,
@@ -1704,7 +1773,7 @@ DWORD FlagsToChange, DWORD Flags)
// mount point.
int
ImDiskCliExtendDevice(DWORD DeviceNumber, LPCWSTR MountPoint,
-LARGE_INTEGER ExtendSize)
+ LARGE_INTEGER ExtendSize)
{
HANDLE device;
DWORD dw;
@@ -1717,21 +1786,27 @@ LARGE_INTEGER ExtendSize)
{
device = ImDiskOpenDeviceByNumber(DeviceNumber,
GENERIC_READ | GENERIC_WRITE);
+
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
+ }
}
else
{
device = ImDiskOpenDeviceByMountPoint(MountPoint,
GENERIC_READ | GENERIC_WRITE);
+
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- GENERIC_READ);
+ GENERIC_READ);
+ }
if (device == INVALID_HANDLE_VALUE)
switch (GetLastError())
- {
+ {
case ERROR_INVALID_PARAMETER:
fputs("This version of Windows only supports drive letters as "
"mount points.\n"
@@ -1755,10 +1830,11 @@ LARGE_INTEGER ExtendSize)
default:
PrintLastError(MountPoint);
return IMDISK_CLI_ERROR_BAD_MOUNT_POINT;
- }
+ }
}
if (device == INVALID_HANDLE_VALUE)
+ {
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
fputs("No such device.\n", stderr);
@@ -1769,11 +1845,13 @@ LARGE_INTEGER ExtendSize)
PrintLastError(L"Error opening device:");
return IMDISK_CLI_ERROR_DEVICE_INACCESSIBLE;
}
+ }
puts("Extending disk size...");
grow_partition.PartitionNumber = 1;
grow_partition.BytesToGrow = ExtendSize;
+
if (!DeviceIoControl(device,
IOCTL_DISK_GROW_PARTITION,
&grow_partition,
@@ -1883,10 +1961,10 @@ wmain(int argc, LPWSTR argv[])
if (wcscmp(argv[1], L"--version") == 0)
{
printf
- ("Control program for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.\n"
+ ("Control program for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.\n"
"Version %i.%i.%i - (Compiled " __DATE__ ")\n"
"\n"
- "Copyright (C) 2004-2018 Olof Lagerkvist.\n"
+ "Copyright (C) 2004-2021 Olof Lagerkvist.\n"
"\n"
"http://www.ltr-data.se olof@ltr-data.se\n"
"\n"
@@ -1936,7 +2014,7 @@ wmain(int argc, LPWSTR argv[])
if (wcslen(argv[0]) == 2 ? argv[0][0] == L'-' : FALSE)
switch (argv[0][1])
- {
+ {
case L'a':
if (op_mode != OP_MODE_NONE)
ImDiskSyntaxHelp();
@@ -2011,10 +2089,13 @@ wmain(int argc, LPWSTR argv[])
for (opt = wcstok(argv[1], L",");
opt != NULL;
opt = wcstok(NULL, L","))
+ {
if (wcscmp(opt, L"ro") == 0)
{
if (IMDISK_READONLY(flags_to_change))
+ {
ImDiskSyntaxHelp();
+ }
flags_to_change |= IMDISK_OPTION_RO;
flags |= IMDISK_OPTION_RO;
@@ -2022,7 +2103,9 @@ wmain(int argc, LPWSTR argv[])
else if (wcscmp(opt, L"rw") == 0)
{
if (IMDISK_READONLY(flags_to_change))
+ {
ImDiskSyntaxHelp();
+ }
flags_to_change |= IMDISK_OPTION_RO;
flags &= ~IMDISK_OPTION_RO;
@@ -2035,7 +2118,9 @@ wmain(int argc, LPWSTR argv[])
else if (wcscmp(opt, L"rem") == 0)
{
if (IMDISK_REMOVABLE(flags_to_change))
+ {
ImDiskSyntaxHelp();
+ }
flags_to_change |= IMDISK_OPTION_REMOVABLE;
flags |= IMDISK_OPTION_REMOVABLE;
@@ -2043,7 +2128,9 @@ wmain(int argc, LPWSTR argv[])
else if (wcscmp(opt, L"fix") == 0)
{
if (IMDISK_REMOVABLE(flags_to_change))
+ {
ImDiskSyntaxHelp();
+ }
flags_to_change |= IMDISK_OPTION_REMOVABLE;
flags &= ~IMDISK_OPTION_REMOVABLE;
@@ -2051,58 +2138,83 @@ wmain(int argc, LPWSTR argv[])
else if (wcscmp(opt, L"saved") == 0)
{
if (op_mode != OP_MODE_EDIT)
+ {
ImDiskSyntaxHelp();
+ }
flags_to_change |= IMDISK_IMAGE_MODIFIED;
flags &= ~IMDISK_IMAGE_MODIFIED;
}
// None of the other options are valid with the -e parameter.
else if (op_mode != OP_MODE_CREATE)
+ {
ImDiskSyntaxHelp();
+ }
else if (wcscmp(opt, L"ip") == 0)
{
- if ((IMDISK_TYPE(flags) != IMDISK_TYPE_PROXY) |
+ if ((IMDISK_TYPE(flags) != IMDISK_TYPE_PROXY) ||
(IMDISK_PROXY_TYPE(flags) != IMDISK_PROXY_TYPE_DIRECT))
+ {
ImDiskSyntaxHelp();
+ }
native_path = TRUE;
flags |= IMDISK_PROXY_TYPE_TCP;
}
else if (wcscmp(opt, L"comm") == 0)
{
- if ((IMDISK_TYPE(flags) != IMDISK_TYPE_PROXY) |
+ if ((IMDISK_TYPE(flags) != IMDISK_TYPE_PROXY) ||
(IMDISK_PROXY_TYPE(flags) != IMDISK_PROXY_TYPE_DIRECT))
+ {
ImDiskSyntaxHelp();
+ }
native_path = TRUE;
flags |= IMDISK_PROXY_TYPE_COMM;
}
else if (wcscmp(opt, L"shm") == 0)
{
- if ((IMDISK_TYPE(flags) != IMDISK_TYPE_PROXY) |
+ if ((IMDISK_TYPE(flags) != IMDISK_TYPE_PROXY) ||
(IMDISK_PROXY_TYPE(flags) != IMDISK_PROXY_TYPE_DIRECT))
+ {
ImDiskSyntaxHelp();
+ }
flags |= IMDISK_PROXY_TYPE_SHM;
}
else if (wcscmp(opt, L"awe") == 0)
{
- if (((IMDISK_TYPE(flags) != IMDISK_TYPE_FILE) &
- (IMDISK_TYPE(flags) != 0)) |
+ if (((IMDISK_TYPE(flags) != IMDISK_TYPE_FILE) &&
+ (IMDISK_TYPE(flags) != 0)) ||
(IMDISK_FILE_TYPE(flags) != 0))
+ {
ImDiskSyntaxHelp();
+ }
flags |= IMDISK_TYPE_FILE | IMDISK_FILE_TYPE_AWEALLOC;
}
else if (wcscmp(opt, L"par") == 0)
{
- if (((IMDISK_TYPE(flags) != IMDISK_TYPE_FILE) &
- (IMDISK_TYPE(flags) != 0)) |
+ if (((IMDISK_TYPE(flags) != IMDISK_TYPE_FILE) &&
+ (IMDISK_TYPE(flags) != 0)) ||
(IMDISK_FILE_TYPE(flags) != 0))
+ {
ImDiskSyntaxHelp();
+ }
flags |= IMDISK_TYPE_FILE | IMDISK_FILE_TYPE_PARALLEL_IO;
}
+ else if (wcscmp(opt, L"buf") == 0)
+ {
+ if (((IMDISK_TYPE(flags) != IMDISK_TYPE_FILE) &&
+ (IMDISK_TYPE(flags) != 0)) ||
+ (IMDISK_FILE_TYPE(flags) != 0))
+ {
+ ImDiskSyntaxHelp();
+ }
+
+ flags |= IMDISK_TYPE_FILE | IMDISK_FILE_TYPE_BUFFERED_IO;
+ }
else if (wcscmp(opt, L"bswap") == 0)
{
flags |= IMDISK_OPTION_BYTE_SWAP;
@@ -2135,6 +2247,7 @@ wmain(int argc, LPWSTR argv[])
{
ImDiskSyntaxHelp();
}
+ }
}
argc--;
@@ -2394,7 +2507,7 @@ wmain(int argc, LPWSTR argv[])
if ((argc < 2) |
(mount_point != NULL) |
((device_number != IMDISK_AUTO_DEVICE_NUMBER) &
- (op_mode != OP_MODE_CREATE)))
+ (op_mode != OP_MODE_CREATE)))
ImDiskSyntaxHelp();
mount_point = _wcsupr(argv[1]);
@@ -2405,7 +2518,7 @@ wmain(int argc, LPWSTR argv[])
default:
ImDiskSyntaxHelp();
- }
+ }
else
ImDiskSyntaxHelp();
}
@@ -2466,7 +2579,7 @@ wmain(int argc, LPWSTR argv[])
{
image_offset.QuadPart +=
partition_information.StartingOffset.QuadPart;
-
+
disk_geometry.Cylinders =
partition_information.PartitionLength;
}
@@ -2487,9 +2600,10 @@ wmain(int argc, LPWSTR argv[])
return ret;
// Notify processes that new device has arrived.
- if ((mount_point != NULL) &&
- (((wcslen(mount_point) == 2) && mount_point[1] == ':') ||
- ((wcslen(mount_point) == 3) && (wcscmp(mount_point + 1, L":\\") == 0))))
+ if (mount_point != NULL &&
+ mount_point[0] != 0 &&
+ (wcscmp(mount_point + 1, L":") == 0 ||
+ wcscmp(mount_point + 1, L":\\") == 0))
{
puts("Notifying applications...");
@@ -2504,7 +2618,7 @@ wmain(int argc, LPWSTR argv[])
case OP_MODE_REMOVE:
if ((device_number == IMDISK_AUTO_DEVICE_NUMBER) &&
((mount_point == NULL) ||
- emergency_remove))
+ emergency_remove))
ImDiskSyntaxHelp();
return ImDiskCliRemoveDevice(device_number, mount_point, force_dismount,
@@ -2553,7 +2667,7 @@ __cdecl
wmainCRTStartup()
{
int argc = 0;
- LPWSTR *argv = CommandLineToArgvW(GetCommandLine(), &argc);
+ LPWSTR* argv = CommandLineToArgvW(GetCommandLine(), &argc);
if (argv == NULL)
{
diff --git a/cli/imdisk.rc b/cli/imdisk.rc
index e96edbd..1ff122c 100644
--- a/cli/imdisk.rc
+++ b/cli/imdisk.rc
@@ -8,8 +8,8 @@
//
VS_VERSION_INFO VERSIONINFO
-FILEVERSION IMDISK_RC_VERSION_FLD, 49
-PRODUCTVERSION IMDISK_RC_VERSION_FLD, 49
+FILEVERSION IMDISK_RC_VERSION_FLD, 50
+PRODUCTVERSION IMDISK_RC_VERSION_FLD, 50
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifndef DEBUG
FILEFLAGS 0
@@ -26,12 +26,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Olof Lagerkvist"
VALUE "FileDescription", "Control program for the ImDisk Virtual Disk Driver"
- VALUE "FileVersion", IMDISK_RC_VERSION_STR ".49"
+ VALUE "FileVersion", IMDISK_RC_VERSION_STR ".50"
VALUE "InternalName", "imdisk"
- VALUE "LegalCopyright", "Copyright © 2004-2018 Olof Lagerkvist."
+ VALUE "LegalCopyright", "Copyright © 2004-2021 Olof Lagerkvist."
VALUE "OriginalFilename", "imdisk.exe"
VALUE "ProductName", "imdisk"
- VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".49"
+ VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".50"
END
END
BLOCK "VarFileInfo"
diff --git a/cpl/Dialogs.rc b/cpl/Dialogs.rc
new file mode 100644
index 0000000..398ee3a
--- /dev/null
+++ b/cpl/Dialogs.rc
@@ -0,0 +1,105 @@
+1 DIALOG 81, 42, 267, 255
+STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Virtual Disks"
+MENU "IDM_MENU_CPL_APPLET"
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+FONT 8, "MS SANS SERIF"
+{
+ CONTROL "", 0, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 2, 252, 44
+ CONTROL 1, 0, STATIC, SS_ICON | WS_CHILD | WS_VISIBLE | WS_GROUP, 14, 15, 21, 20
+ CONTROL "Virtual disks work just like physical disks. Image files can be mounted as virtual disks and used like normal drives.", 0, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 43, 18, 208, 18
+ CONTROL "Available Virtual Disks:", 0, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 52, 252, 177
+ CONTROL "Current virtual devices", 101, "SysListView32", LVS_EX_FULLROWSELECT | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 14, 66, 238, 136
+ CONTROL "&Unmount", 11855, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 15, 207, 50, 15
+ CONTROL "&Extend...", 11854, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 70, 207, 50, 15
+ CONTROL "F&ormat...", 11853, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 125, 207, 50, 15
+ CONTROL "Save &As...", 11852, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 180, 207, 50, 15
+ CONTROL "Mount &New...", 11840, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 234, 50, 15
+ CONTROL "&Refresh", 11843, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 62, 234, 50, 15
+}
+
+2 DIALOG 111, 12, 268, 321
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_CONTROLPARENT
+CAPTION "Mount New Virtual Disk"
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+FONT 8, "MS SANS SERIF"
+{
+ CONTROL "", 0, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 4, 253, 44
+ CONTROL 303, 0, STATIC, SS_ICON | WS_CHILD | WS_VISIBLE | WS_GROUP, 14, 17, 21, 20
+ CONTROL "To create a virtual disk in memory instead of using an image file, specify the size of disk and leave the Image file field blank.", 112, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE, 46, 19, 202, 18
+ CONTROL "Specify Image File:", 0, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 54, 253, 34
+ CONTROL "", 102, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 14, 68, 183, 13
+ CONTROL "Bro&wse...", 111, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 203, 67, 50, 15
+ CONTROL "Specify Disk Size and Units:", 113, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 94, 253, 50
+ CONTROL "Virtual Disk &Size:", 0, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 14, 110, 61, 9
+ CONTROL "(current image file size)", 105, EDIT, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 81, 108, 87, 13
+ CONTROL "Bytes", 114, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 14, 126, 32, 13
+ CONTROL "Blocks", 101, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 54, 126, 36, 13
+ CONTROL "Kilobytes", 115, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 96, 126, 45, 13
+ CONTROL "Megabytes", 116, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 145, 126, 51, 13
+ CONTROL "Gigabytes", 117, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 201, 126, 47, 13
+ CONTROL "Specify Image File Offset and Units:", 127, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 148, 253, 50
+ CONTROL "Image File &Offset:", 0, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 14, 164, 61, 9
+ CONTROL "0", 123, EDIT, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 81, 162, 87, 13
+ CONTROL "Bytes", 128, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 14, 181, 32, 13
+ CONTROL "Blocks", 129, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 54, 181, 36, 13
+ CONTROL "Kilobytes", 130, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 96, 181, 44, 13
+ CONTROL "Megabytes", 131, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 145, 181, 48, 13
+ CONTROL "Gigabytes", 132, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 201, 181, 48, 13
+ CONTROL "Select Device Type:", 107, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 203, 253, 37
+ CONTROL "&Auto", 108, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 14, 217, 32, 13
+ CONTROL "Fixed &Disk", 109, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 55, 217, 54, 13
+ CONTROL "&Floppy Disk", 118, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 114, 217, 57, 13
+ CONTROL "&CD/DVD-ROM", 110, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 176, 217, 64, 13
+ CONTROL "Select Attributes:", 0, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 245, 253, 50
+ CONTROL "Assign Drive &Letter:", 124, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE, 14, 261, 65, 9
+ CONTROL "", 103, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 81, 258, 87, 13
+ CONTROL "Create a Copy in &Memory", 106, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 14, 278, 97, 9
+ CONTROL "&Read-only access", 104, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 111, 278, 75, 9
+ CONTROL "Remo&vable Drive", 121, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 187, 278, 69, 9
+ CONTROL "OK", 1, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP, 155, 300, 50, 15
+ CONTROL "Cancel", 2, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 210, 300, 50, 14
+}
+
+3 DIALOG 21, 11, 247, 28
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "Virtual Disks"
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+FONT 8, "MS SANS SERIF"
+{
+ CONTROL "", 101, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE, 4, 4, 196, 20
+ CONTROL "Cancel", 2, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_TABSTOP, 204, 12, 40, 14
+}
+
+4 DIALOG 173, 56, 228, 72
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_CONTROLPARENT
+CAPTION "Extend Disk Size"
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+FONT 8, "MS SANS SERIF"
+{
+ CONTROL "Enter the size you want to add to the selected virtual disk:", 104, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE, 4, 4, 164, 16
+ CONTROL "", 102, EDIT, ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 4, 24, 164, 13
+ CONTROL "Size Unit:", 103, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 4, 40, 220, 28
+ CONTROL "&Bytes", 114, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 8, 52, 32, 13
+ CONTROL "B&locks", 101, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 41, 52, 36, 13
+ CONTROL "&Kilobytes", 115, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 78, 52, 44, 13
+ CONTROL "&Megabytes", 116, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 123, 52, 48, 13
+ CONTROL "&Gigabytes", 117, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 173, 52, 48, 13
+ CONTROL "OK", 1, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP, 172, 5, 50, 15
+ CONTROL "Cancel", 2, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 172, 24, 50, 15
+}
+
+5 DIALOG 14, 11, 308, 196
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_CONTROLPARENT
+CAPTION ""
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+FONT 8, "MS Sans Serif"
+{
+ CONTROL "OK", 1, BUTTON, BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 256, 180, 50, 14
+ CONTROL "", 101, EDIT, ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 0, 0, 308, 176
+}
+
diff --git a/cpl/Icons/CD.bmp b/cpl/Icons/CD.bmp
new file mode 100644
index 0000000..4b57347
Binary files /dev/null and b/cpl/Icons/CD.bmp differ
diff --git a/cpl/amd64/imdisk.exp b/cpl/amd64/imdisk.exp
index 09be2b9..278c890 100644
Binary files a/cpl/amd64/imdisk.exp and b/cpl/amd64/imdisk.exp differ
diff --git a/cpl/amd64/imdisk.lib b/cpl/amd64/imdisk.lib
index ba101b3..c79c5f9 100644
Binary files a/cpl/amd64/imdisk.lib and b/cpl/amd64/imdisk.lib differ
diff --git a/cpl/cpl.inf b/cpl/cpl.inf
new file mode 100644
index 0000000..679bb15
--- /dev/null
+++ b/cpl/cpl.inf
@@ -0,0 +1,54 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = cpl.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk Virtual Disk Driver API library"
+
+
+[SourceDisksFiles.x86]
+imdisk.cpl = 1, i386
+
+[SourceDisksFiles.ia64]
+imdisk.cpl = 1, ia64
+
+[SourceDisksFiles.amd64]
+imdisk.cpl = 1, amd64
+
+[SourceDisksFiles.arm]
+imdisk.cpl = 1, arm
+
+[SourceDisksFiles.arm64]
+imdisk.cpl = 1, arm64
+
+[DestinationDirs]
+ImDiskCplExeFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ImDiskCplExeFiles
+
+
+[ImDiskCplExeFiles]
+imdisk.cpl
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDiskCpl, , ImDiskCpl
+
+
+[ImDiskCpl]
+DisplayName = "ImDisk Virtual Disk Driver API library"
+StartType = 2
+ServiceType = 16
+ErrorControl = 0
+ServiceBinary = %11%\imdisk.cpl
diff --git a/cpl/cpl.vcxproj b/cpl/cpl.vcxproj
index f42f62c..57bb44e 100644
--- a/cpl/cpl.vcxproj
+++ b/cpl/cpl.vcxproj
@@ -325,17 +325,26 @@
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
diff --git a/cpl/drvio.c b/cpl/drvio.c
index fea242f..ebcf076 100644
--- a/cpl/drvio.c
+++ b/cpl/drvio.c
@@ -1,7 +1,7 @@
/*
API library for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.
-Copyright (C) 2007-2018 Olof Lagerkvist.
+Copyright (C) 2007-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -54,7 +54,7 @@ typedef struct _KNOWN_FORMAT
{
LPCWSTR Extension;
LONGLONG Offset;
-} KNOWN_FORMAT, *PKNOWN_FORMAT;
+} KNOWN_FORMAT, * PKNOWN_FORMAT;
KNOWN_FORMAT KnownFormats[] = {
{ L"nrg", 600 << 9 },
@@ -67,7 +67,7 @@ ImDiskFlushWindowMessages(HWND hWnd)
{
#ifndef CORE_BUILD
MSG msg;
-
+
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
if (!IsDialogMessage(hWnd, &msg))
@@ -99,6 +99,25 @@ ImDiskAllocPrintF(LPCWSTR lpMessage, ...)
return lpBuf;
}
+IMDISK_API LPSTR
+CDECL
+ImDiskAllocPrintFA(LPCSTR lpMessage, ...)
+{
+ va_list param_list;
+ LPSTR lpBuf = NULL;
+
+ va_start(param_list, lpMessage);
+
+ if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_STRING, lpMessage, 0, 0,
+ (LPSTR)&lpBuf, 0, ¶m_list))
+ {
+ return NULL;
+ }
+
+ return lpBuf;
+}
+
ULONGLONG APIFlags;
IMDISK_API ULONGLONG
@@ -200,8 +219,8 @@ MsgBoxLastError(HWND hWnd, LPCWSTR Prefix)
IMDISK_API VOID
WINAPI
ImDiskGetPartitionTypeName(IN BYTE PartitionType,
-IN OUT LPWSTR Name,
-IN DWORD NameSize)
+ IN OUT LPWSTR Name,
+ IN DWORD NameSize)
{
LPWSTR name;
WCHAR other_type[] = L"Type XXh";
@@ -278,7 +297,7 @@ IN DWORD NameSize)
IMDISK_API BOOL
WINAPI
ImDiskGetOffsetByFileExt(IN LPCWSTR ImageFile,
-IN OUT PLARGE_INTEGER Offset)
+ IN OUT PLARGE_INTEGER Offset)
{
LPCWSTR path_sep;
PKNOWN_FORMAT known_format;
@@ -299,12 +318,14 @@ IN OUT PLARGE_INTEGER Offset)
for (known_format = KnownFormats;
known_format <
KnownFormats + _countof(KnownFormats);
- known_format++)
+ known_format++)
+ {
if (_wcsicmp(ImageFile, known_format->Extension) == 0)
{
Offset->QuadPart = known_format->Offset;
return TRUE;
}
+ }
return FALSE;
}
@@ -406,7 +427,7 @@ ImDiskGetPartitionInformation(IN LPCWSTR ImageFile,
return bResult;
}
-typedef BOOL(WINAPI *ImDiskReadFileProc)(IN HANDLE Handle,
+typedef BOOL(WINAPI* ImDiskReadFileProc)(IN HANDLE Handle,
IN OUT LPVOID Buffer,
IN LARGE_INTEGER Offset,
IN DWORD NumberOfBytesToRead,
@@ -415,15 +436,17 @@ typedef BOOL(WINAPI *ImDiskReadFileProc)(IN HANDLE Handle,
IMDISK_API BOOL
WINAPI
ImDiskReadFileHandle(IN HANDLE Handle,
-IN OUT LPVOID Buffer,
-IN LARGE_INTEGER Offset,
-IN DWORD NumberOfBytesToRead,
-IN OUT LPDWORD NumberOfBytesRead)
+ IN OUT LPVOID Buffer,
+ IN LARGE_INTEGER Offset,
+ IN DWORD NumberOfBytesToRead,
+ IN OUT LPDWORD NumberOfBytesRead)
{
if (SetFilePointer(Handle, Offset.LowPart, &Offset.HighPart,
- FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- if (GetLastError() != NO_ERROR)
- return FALSE;
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER &&
+ GetLastError() != NO_ERROR)
+ {
+ return FALSE;
+ }
return ReadFile(Handle,
Buffer,
@@ -613,7 +636,7 @@ typedef struct _IMDISKGETPARTITIONINFOINDIRECTEX_DATA
{
PPARTITION_INFORMATION Next;
DWORD Count;
-} IMDISKGETPARTITIONINFOINDIRECTEX_DATA, *PIMDISKGETPARTITIONINFOINDIRECTEX_DATA;
+} IMDISKGETPARTITIONINFOINDIRECTEX_DATA, * PIMDISKGETPARTITIONINFOINDIRECTEX_DATA;
BOOL CALLBACK
GotPartInfoForArray(LPVOID UserData, PPARTITION_INFORMATION PartitionInformation)
@@ -696,11 +719,11 @@ ImDiskGetSinglePartitionInfoIndirect(IN HANDLE Handle,
IMDISK_API BOOL
WINAPI
ImDiskGetPartitionInfoIndirect(IN HANDLE Handle,
-IN ImDiskReadFileProc ReadFileProc,
-IN DWORD SectorSize OPTIONAL,
-IN PLARGE_INTEGER Offset OPTIONAL,
-IN OUT PPARTITION_INFORMATION
-PartitionInformation)
+ IN ImDiskReadFileProc ReadFileProc,
+ IN DWORD SectorSize OPTIONAL,
+ IN PLARGE_INTEGER Offset OPTIONAL,
+ IN OUT PPARTITION_INFORMATION
+ PartitionInformation)
{
LPBYTE buffer = NULL;
DWORD read_size = 0;
@@ -802,7 +825,7 @@ PartitionInformation)
IMDISK_API BOOL
WINAPI
ImDiskImageContainsISOFS(IN LPCWSTR ImageFile,
-IN PLARGE_INTEGER Offset OPTIONAL)
+ IN PLARGE_INTEGER Offset OPTIONAL)
{
HANDLE hImageFile;
BOOL bResult;
@@ -829,8 +852,8 @@ IN PLARGE_INTEGER Offset OPTIONAL)
IMDISK_API BOOL
WINAPI
ImDiskImageContainsISOFSIndirect(IN HANDLE Handle,
-IN ImDiskReadFileProc ReadFileProc,
-IN PLARGE_INTEGER Offset OPTIONAL)
+ IN ImDiskReadFileProc ReadFileProc,
+ IN PLARGE_INTEGER Offset OPTIONAL)
{
const char magic[] = { 0x01, 'C', 'D', '0', '0', '1', 0x01 };
char buffer[sizeof(magic)];
@@ -922,7 +945,7 @@ typedef struct _REPARSE_DATA_JUNCTION
WORD DisplayNameOffset;
WORD DisplayNameLength;
BYTE Data[65536];
-} REPARSE_DATA_JUNCTION, *PREPARSE_DATA_JUNCTION;
+} REPARSE_DATA_JUNCTION, * PREPARSE_DATA_JUNCTION;
IMDISK_API BOOL
WINAPI
@@ -939,8 +962,14 @@ ImDiskCreateMountPoint(LPCWSTR MountPoint, LPCWSTR Target)
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer) + iSize +
2 + iSize + 2;
- if ((wcslen(MountPoint) == 2) &&
- (MountPoint[1] == L':'))
+ if (MountPoint == NULL || MountPoint[0] == 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if ((wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
{
WCHAR GlobalMountPoint[] = L"Global\\ :";
DWORD ddd_flags = DDD_RAW_TARGET_PATH;
@@ -953,7 +982,7 @@ ImDiskCreateMountPoint(LPCWSTR MountPoint, LPCWSTR Target)
ddd_flags |= DDD_NO_BROADCAST_SYSTEM;
}
-#ifdef _WIN64
+#ifndef _M_IX86
if (DefineDosDevice(ddd_flags, GlobalMountPoint, Target))
return TRUE;
@@ -987,20 +1016,20 @@ ImDiskCreateMountPoint(LPCWSTR MountPoint, LPCWSTR Target)
if (hDir == INVALID_HANDLE_VALUE)
return FALSE;
- if ((iSize + 6 > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) | (iSize == 0))
+ if ((iSize + 6 > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) || (iSize == 0))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- ReparseData = HeapAlloc(GetProcessHeap(),
+ ReparseData = (PREPARSE_DATA_BUFFER)HeapAlloc(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
buffer_size);
__analysis_assume(ReparseData != NULL);
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
-
+
ReparseData->ReparseDataLength = data_length;
ReparseData->MountPointReparseBuffer.SubstituteNameLength = (WORD)iSize;
@@ -1043,8 +1072,14 @@ ImDiskRemoveMountPoint(LPCWSTR MountPoint)
HANDLE hDir;
DWORD dw;
- if (((wcslen(MountPoint) == 2) && MountPoint[1] == ':') ||
- ((wcslen(MountPoint) == 3) && (wcscmp(MountPoint + 1, L":\\") == 0)))
+ if (MountPoint == NULL || MountPoint[0] == 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if ((wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
{
DWORD_PTR dwp;
DEV_BROADCAST_VOLUME dev_broadcast_volume = {
@@ -1070,7 +1105,7 @@ ImDiskRemoveMountPoint(LPCWSTR MountPoint)
SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, MountPoint, NULL);
#endif
}
-#ifndef _WIN64
+#ifdef _M_IX86
else if (!IMDISK_GTE_WIN2K())
{
}
@@ -1218,7 +1253,7 @@ ImDiskOpenDeviceByMountPoint(LPCWSTR MountPoint, DWORD AccessMode)
if ((MountPoint[0] != 0) &&
((wcscmp(MountPoint + 1, L":") == 0) ||
- (wcscmp(MountPoint + 1, L":\\") == 0)))
+ (wcscmp(MountPoint + 1, L":\\") == 0)))
{
DriveLetterPath[12] = MountPoint[0];
@@ -1248,7 +1283,7 @@ ImDiskOpenDeviceByMountPoint(LPCWSTR MountPoint, DWORD AccessMode)
if (hDir == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
- ReparseData = HeapAlloc(GetProcessHeap(),
+ ReparseData = (PREPARSE_DATA_BUFFER)HeapAlloc(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
buffer_size);
@@ -1275,14 +1310,14 @@ ImDiskOpenDeviceByMountPoint(LPCWSTR MountPoint, DWORD AccessMode)
DeviceName.Length =
ReparseData->MountPointReparseBuffer.SubstituteNameLength;
-
+
DeviceName.Buffer = (PWSTR)
((PUCHAR)ReparseData->MountPointReparseBuffer.PathBuffer +
- ReparseData->MountPointReparseBuffer.SubstituteNameOffset);
-
+ ReparseData->MountPointReparseBuffer.SubstituteNameOffset);
+
DeviceName.MaximumLength = DeviceName.Length;
}
-
+
if (DeviceName.Buffer[(DeviceName.Length >> 1) - 1] == L'\\')
{
DeviceName.Buffer[(DeviceName.Length >> 1) - 1] = 0;
@@ -1309,7 +1344,9 @@ ImDiskCheckDriverVersion(HANDLE Device)
NULL, 0,
&VersionCheck, sizeof VersionCheck,
&BytesReturned, NULL))
+ {
return FALSE;
+ }
SetLastError(NO_ERROR);
@@ -1325,7 +1362,7 @@ ImDiskCheckDriverVersion(HANDLE Device)
IMDISK_API BOOL
WINAPI
ImDiskGetVersion(PULONG LibraryVersion,
-PULONG DriverVersion)
+ PULONG DriverVersion)
{
if (LibraryVersion != NULL)
*LibraryVersion = IMDISK_VERSION;
@@ -1380,9 +1417,14 @@ ImDiskFindFreeDriveLetter()
{
DWORD logical_drives = GetLogicalDrives();
WCHAR search;
+
for (search = L'D'; search <= L'Z'; search++)
+ {
if ((logical_drives & (1 << (search - L'A'))) == 0)
+ {
return search;
+ }
+ }
return 0;
}
@@ -1420,7 +1462,7 @@ ImDiskGetDeviceList()
IMDISK_API BOOL
WINAPI
ImDiskGetDeviceListEx(IN ULONG ListLength,
-OUT ULONG *DeviceList)
+ OUT ULONG* DeviceList)
{
UNICODE_STRING file_name;
HANDLE driver;
@@ -1446,7 +1488,7 @@ OUT ULONG *DeviceList)
NtClose(driver);
- if ((dw == sizeof(ULONG)) &
+ if ((dw == sizeof(ULONG)) &&
(*DeviceList > 0))
{
SetLastError(ERROR_MORE_DATA);
@@ -1460,8 +1502,8 @@ OUT ULONG *DeviceList)
IMDISK_API BOOL
WINAPI
ImDiskQueryDevice(DWORD DeviceNumber,
-PIMDISK_CREATE_DATA CreateData,
-ULONG CreateDataSize)
+ PIMDISK_CREATE_DATA CreateData,
+ ULONG CreateDataSize)
{
HANDLE device = ImDiskOpenDeviceByNumber(DeviceNumber, FILE_READ_ATTRIBUTES);
DWORD dw;
@@ -1495,12 +1537,12 @@ ULONG CreateDataSize)
IMDISK_API BOOL
WINAPI
ImDiskCreateDevice(HWND hWnd,
-PDISK_GEOMETRY DiskGeometry,
-PLARGE_INTEGER ImageOffset,
-DWORD Flags,
-LPCWSTR FileName,
-BOOL NativePath,
-LPWSTR MountPoint)
+ PDISK_GEOMETRY DiskGeometry,
+ PLARGE_INTEGER ImageOffset,
+ DWORD Flags,
+ LPCWSTR FileName,
+ BOOL NativePath,
+ LPWSTR MountPoint)
{
return ImDiskCreateDeviceEx(hWnd,
NULL,
@@ -1515,13 +1557,13 @@ LPWSTR MountPoint)
IMDISK_API BOOL
WINAPI
ImDiskCreateDeviceEx(HWND hWnd,
-LPDWORD DeviceNumber,
-PDISK_GEOMETRY DiskGeometry,
-PLARGE_INTEGER ImageOffset,
-DWORD Flags,
-LPCWSTR FileName,
-BOOL NativePath,
-LPWSTR MountPoint)
+ LPDWORD DeviceNumber,
+ PDISK_GEOMETRY DiskGeometry,
+ PLARGE_INTEGER ImageOffset,
+ DWORD Flags,
+ LPCWSTR FileName,
+ BOOL NativePath,
+ LPWSTR MountPoint)
{
PIMDISK_CREATE_DATA create_data;
UNICODE_STRING file_name;
@@ -1554,37 +1596,49 @@ LPWSTR MountPoint)
if (!ImDiskStartService(IMDISK_DRIVER_NAME))
switch (GetLastError())
- {
+ {
case ERROR_SERVICE_DOES_NOT_EXIST:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The ImDisk Virtual Disk Driver is not installed. "
- L"Please re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The ImDisk Virtual Disk Driver is not installed. "
+ L"Please re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"Cannot load imdisk.sys. "
- L"Please re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"Cannot load imdisk.sys. "
+ L"Please re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
case ERROR_SERVICE_DISABLED:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The ImDisk Virtual Disk Driver is disabled.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The ImDisk Virtual Disk Driver is disabled.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
default:
if (hWnd != NULL)
+ {
MsgBoxLastError(hWnd,
- L"Error loading ImDisk Virtual Disk Driver:");
+ L"Error loading ImDisk Virtual Disk Driver:");
+ }
+
return FALSE;
- }
+ }
ImDiskFlushWindowMessages(NULL);
@@ -1595,24 +1649,27 @@ LPWSTR MountPoint)
if (!ImDiskCheckDriverVersion(driver))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The version of the ImDisk Virtual Disk Driver "
- L"(imdisk.sys) installed on this system does not match "
- L"the version of this control program. Please reinstall "
- L"ImDisk to make sure that all components of it on this "
- L"system are from the same install package. You may have "
- L"to restart your computer if you still see this message "
- L"after reinstalling.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The version of the ImDisk Virtual Disk Driver "
+ L"(imdisk.sys) installed on this system does not match "
+ L"the version of this control program. Please reinstall "
+ L"ImDisk to make sure that all components of it on this "
+ L"system are from the same install package. You may have "
+ L"to restart your computer if you still see this message "
+ L"after reinstalling.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
// Physical memory allocation requires the AWEAlloc driver.
- if (((IMDISK_TYPE(Flags) == IMDISK_TYPE_FILE) |
- (IMDISK_TYPE(Flags) == 0)) &
+ if (((IMDISK_TYPE(Flags) == IMDISK_TYPE_FILE) ||
+ (IMDISK_TYPE(Flags) == 0)) &&
(IMDISK_FILE_TYPE(Flags) == IMDISK_FILE_TYPE_AWEALLOC))
{
HANDLE awealloc;
@@ -1643,26 +1700,35 @@ LPWSTR MountPoint)
{
case ERROR_SERVICE_DOES_NOT_EXIST:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The AWEAlloc driver is not installed. Please "
- L"re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The AWEAlloc driver is not installed. Please "
+ L"re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
break;
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"Cannot load the AWEAlloc driver. Please "
- L"re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"Cannot load the AWEAlloc driver. Please "
+ L"re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
break;
case ERROR_SERVICE_DISABLED:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The AWEAlloc driver is disabled.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The AWEAlloc driver is disabled.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
break;
default:
@@ -1675,93 +1741,119 @@ LPWSTR MountPoint)
}
}
// Proxy reconnection types requires the user mode service.
- else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &
- ((IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_TCP) |
- (IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_COMM)))
+ else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &&
+ ((IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_TCP) ||
+ (IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_COMM)))
{
- if (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- if (ImDiskStartService(IMDPROXY_SVC))
+ if (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0) &&
+ GetLastError() == ERROR_FILE_NOT_FOUND)
+ {
+ if (ImDiskStartService(IMDPROXY_SVC))
+ {
+ while (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
{
- while (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- Sleep(500);
- else
- break;
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ Sleep(500);
+ else
+ break;
+ }
- if (hWnd != NULL)
- SetWindowText
- (hWnd,
+ if (hWnd != NULL)
+ {
+ SetWindowText(hWnd,
L"ImDisk Virtual Disk Driver Helper Service started.");
}
- else
+ }
+ else
+ {
+ switch (GetLastError())
{
- switch (GetLastError())
+ case ERROR_SERVICE_DOES_NOT_EXIST:
+ if (hWnd != NULL)
{
- case ERROR_SERVICE_DOES_NOT_EXIST:
- if (hWnd != NULL)
- MessageBox(hWnd,
+ MessageBox(hWnd,
L"The ImDisk Virtual Disk Driver Helper "
L"Service is not installed. Please re-install "
L"ImDisk.",
L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
- break;
+ }
+
+ break;
- case ERROR_PATH_NOT_FOUND:
- case ERROR_FILE_NOT_FOUND:
- if (hWnd != NULL)
- MessageBox(hWnd,
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_FILE_NOT_FOUND:
+ if (hWnd != NULL)
+ {
+ MessageBox(hWnd,
L"Cannot start the ImDisk Virtual Disk Driver "
L"Helper Service. Please re-install ImDisk.",
L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
- break;
+ }
+
+ break;
- case ERROR_SERVICE_DISABLED:
- if (hWnd != NULL)
- MessageBox(hWnd,
+ case ERROR_SERVICE_DISABLED:
+ if (hWnd != NULL)
+ {
+ MessageBox(hWnd,
L"The ImDisk Virtual Disk Driver Helper "
L"Service is disabled.",
L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
- break;
+ }
+
+ break;
- default:
- if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
+ default:
+ if (hWnd != NULL)
+ {
+ MsgBoxLastError(hWnd,
L"Error starting ImDisk Virtual Disk Driver Helper "
L"Service:");
}
-
- NtClose(driver);
- return FALSE;
}
+
+ NtClose(driver);
+ return FALSE;
+ }
+ }
}
if (FileName == NULL)
+ {
RtlInitUnicodeString(&file_name, NULL);
+ }
else if (NativePath)
{
if (!RtlCreateUnicodeString(&file_name, FileName))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd, L"Memory allocation error.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
}
}
- else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &
+ else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &&
(IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_SHM))
{
LPWSTR namespace_prefix;
LPWSTR prefixed_name;
HANDLE h = CreateFile(L"\\\\?\\Global", 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if ((h == INVALID_HANDLE_VALUE) &
+
+ if ((h == INVALID_HANDLE_VALUE) &&
(GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
namespace_prefix = L"\\BaseNamedObjects\\";
+ }
else
+ {
namespace_prefix = L"\\BaseNamedObjects\\Global\\";
+ }
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
@@ -1775,9 +1867,13 @@ LPWSTR MountPoint)
if (!RtlCreateUnicodeString(&file_name, prefixed_name))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd, L"Memory allocation error.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
}
}
@@ -1786,9 +1882,13 @@ LPWSTR MountPoint)
if (!RtlDosPathNameToNtPathName_U(FileName, &file_name, NULL, NULL))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd, L"Memory allocation error.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
}
}
@@ -1803,7 +1903,7 @@ LPWSTR MountPoint)
// Check if mount point is a drive letter or junction point
if ((MountPoint != NULL) && (MountPoint[0] != 0) &&
((wcscmp(MountPoint + 1, L":") == 0) ||
- ((wcscmp(MountPoint + 1, L":\\") == 0))))
+ ((wcscmp(MountPoint + 1, L":\\") == 0))))
{
create_data->DriveLetter = MountPoint[0];
}
@@ -1860,10 +1960,14 @@ LPWSTR MountPoint)
IMDISK_DEVICE_BASE_NAME L"%u", create_data->DeviceNumber);
device_path[_countof(device_path) - 1] = 0;
- if ((wcslen(MountPoint) == 2) &&
- (MountPoint[1] == L':'))
+ if (MountPoint != NULL && MountPoint[0] != 0 &&
+ (wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
{
-#ifndef _WIN64
+ WCHAR drive_letter[] = L" :";
+ drive_letter[0] = MountPoint[0];
+
+#ifdef _M_IX86
if (!IMDISK_GTE_WINXP())
{
DWORD ddd_flags = DDD_RAW_TARGET_PATH;
@@ -1874,18 +1978,21 @@ LPWSTR MountPoint)
ddd_flags |= DDD_NO_BROADCAST_SYSTEM;
}
- if (!DefineDosDevice(ddd_flags, MountPoint, device_path))
+ if (!DefineDosDevice(ddd_flags, drive_letter, device_path))
+ {
if (hWnd != NULL)
MsgBoxLastError(hWnd, L"Error creating mount point:");
+ }
}
#endif
if (hWnd != NULL)
- SetWindowText
- (hWnd,
- L"Notifying applications that device has been created...");
+ {
+ SetWindowText(hWnd,
+ L"Notifying applications that device has been created...");
+ }
- ImDiskNotifyShellDriveLetter(hWnd, MountPoint);
+ ImDiskNotifyShellDriveLetter(hWnd, drive_letter);
}
else
{
@@ -1899,10 +2006,11 @@ LPWSTR MountPoint)
IMDISK_API BOOL
WINAPI
ImDiskNotifyShellDriveLetter(HWND hWnd,
-LPWSTR DriveLetterPath)
+ LPWSTR DriveLetterPath)
{
#ifndef CORE_BUILD
DWORD_PTR dwp;
+
DEV_BROADCAST_VOLUME dev_broadcast_volume = {
sizeof(DEV_BROADCAST_VOLUME),
DBT_DEVTYP_VOLUME
@@ -1945,19 +2053,20 @@ LPWSTR DriveLetterPath)
4000,
&dwp);
- /* Tried PostMessage instead of SendMessageTimeout
+#if 0 // Tried PostMessage instead of SendMessageTimeout
PostMessage(HWND_BROADCAST,
- WM_DEVICECHANGE,
- DBT_DEVICEARRIVAL,
- (LPARAM)&dev_broadcast_volume);
+ WM_DEVICECHANGE,
+ DBT_DEVICEARRIVAL,
+ (LPARAM)&dev_broadcast_volume);
dev_broadcast_volume.dbcv_flags = DBTF_MEDIA;
PostMessage(HWND_BROADCAST,
- WM_DEVICECHANGE,
- DBT_DEVICEARRIVAL,
- (LPARAM)&dev_broadcast_volume);
- */
+ WM_DEVICECHANGE,
+ DBT_DEVICEARRIVAL,
+ (LPARAM)&dev_broadcast_volume);
+#endif
+
#endif
return TRUE;
@@ -1966,17 +2075,19 @@ LPWSTR DriveLetterPath)
IMDISK_API BOOL
WINAPI
ImDiskNotifyRemovePending(HWND hWnd,
-WCHAR DriveLetter)
+ WCHAR DriveLetter)
{
#ifndef CORE_BUILD
DEV_BROADCAST_VOLUME dev_broadcast_volume = {
sizeof(DEV_BROADCAST_VOLUME),
DBT_DEVTYP_VOLUME
};
+
DWORD_PTR dwp;
dev_broadcast_volume.dbcv_unitmask = 1 << (DriveLetter - L'A');
+#ifdef SEND_DBT_DEVICEQUERYREMOVE
SendMessageTimeout(HWND_BROADCAST,
WM_DEVICECHANGE,
DBT_DEVICEQUERYREMOVE,
@@ -1984,6 +2095,7 @@ WCHAR DriveLetter)
SMTO_BLOCK | SMTO_ABORTIFHUNG,
4000,
&dwp);
+#endif
SendMessageTimeout(HWND_BROADCAST,
WM_DEVICECHANGE,
@@ -2000,8 +2112,8 @@ WCHAR DriveLetter)
IMDISK_API BOOL
WINAPI
ImDiskRemoveDevice(HWND hWnd,
-DWORD DeviceNumber,
-LPCWSTR MountPoint)
+ DWORD DeviceNumber,
+ LPCWSTR MountPoint)
{
HANDLE device;
DWORD dw;
@@ -2017,11 +2129,11 @@ LPCWSTR MountPoint)
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- FILE_READ_ATTRIBUTES);
+ FILE_READ_ATTRIBUTES);
}
else if ((wcscmp(MountPoint + 1, L":") == 0) ||
(wcscmp(MountPoint + 1, L":\\") == 0))
@@ -2030,13 +2142,14 @@ LPCWSTR MountPoint)
drive_letter_path[4] = MountPoint[0];
// Notify processes that this device is about to be removed.
- if (((APIFlags & IMDISK_API_NO_BROADCAST_NOTIFY) == 0) &
- (MountPoint[0] >= L'A') & (MountPoint[0] <= L'Z'))
+ if (((APIFlags & IMDISK_API_NO_BROADCAST_NOTIFY) == 0) &&
+ (MountPoint[0] >= L'A') && (MountPoint[0] <= L'Z'))
{
if (hWnd != NULL)
- SetWindowText
- (hWnd,
- L"Notifying applications that device is being removed...");
+ {
+ SetWindowText(hWnd,
+ L"Notifying applications that device is being removed...");
+ }
ImDiskNotifyRemovePending(hWnd, MountPoint[0]);
}
@@ -2050,16 +2163,20 @@ LPCWSTR MountPoint)
NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if (device == INVALID_HANDLE_VALUE)
+ {
device = CreateFile(drive_letter_path,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ }
if (device == INVALID_HANDLE_VALUE)
+ {
device = CreateFile(drive_letter_path,
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ }
}
else
{
@@ -2070,32 +2187,41 @@ LPCWSTR MountPoint)
GENERIC_READ | GENERIC_WRITE);
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- GENERIC_READ);
+ GENERIC_READ);
+ }
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- FILE_READ_ATTRIBUTES);
+ FILE_READ_ATTRIBUTES);
+ }
}
if (device == INVALID_HANDLE_VALUE)
{
if (hWnd != NULL)
MsgBoxLastError(hWnd, L"Error opening device:");
+
return FALSE;
}
- if (!ImDiskCheckDriverVersion(device))
- if (GetLastError() != NO_ERROR)
+ if (!ImDiskCheckDriverVersion(device) &&
+ GetLastError() != NO_ERROR)
+ {
+ NtClose(device);
+
+ if (hWnd != NULL)
{
- NtClose(device);
- if (hWnd != NULL)
- ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"ImDisk Virtual Disk Driver",
+ ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP,
+ L"ImDisk Virtual Disk Driver",
L"Not an ImDisk Virtual Disk: '%1'", MountPoint);
-
- return FALSE;
}
+ return FALSE;
+ }
+
if (hWnd != NULL)
SetWindowText(hWnd, L"Flushing file buffers...");
@@ -2112,8 +2238,11 @@ LPCWSTR MountPoint)
0,
&dw,
NULL))
+ {
if (APIFlags & IMDISK_API_FORCE_DISMOUNT)
+ {
force_dismount = TRUE;
+ }
else if (hWnd == NULL)
{
NtClose(device);
@@ -2133,22 +2262,26 @@ LPCWSTR MountPoint)
return FALSE;
}
else
+ {
force_dismount = TRUE;
+ }
+ }
- if (hWnd != NULL)
- SetWindowText(hWnd, L"Dismounting filesystem...");
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"Dismounting filesystem...");
- DeviceIoControl(device,
- FSCTL_DISMOUNT_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &dw,
- NULL);
+ DeviceIoControl(device,
+ FSCTL_DISMOUNT_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &dw,
+ NULL);
- if (force_dismount)
- DeviceIoControl(device,
+ if (force_dismount)
+ {
+ DeviceIoControl(device,
FSCTL_LOCK_VOLUME,
NULL,
0,
@@ -2156,72 +2289,77 @@ LPCWSTR MountPoint)
0,
&dw,
NULL);
+ }
- // If interactive mode, check if image has been modified and if so ask user
- // if it should be saved first.
+ // If interactive mode, check if image has been modified and if so ask user
+ // if it should be saved first.
#ifndef CORE_BUILD
- if (hWnd != NULL)
- if (!ImDiskInteractiveCheckSave(hWnd, device))
- {
- NtClose(device);
- return FALSE;
- }
+ if (hWnd != NULL && !ImDiskInteractiveCheckSave(hWnd, device))
+ {
+ NtClose(device);
+ return FALSE;
+ }
#endif
- if (hWnd != NULL)
- SetWindowText(hWnd, L"Removing device...");
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"Removing device...");
- if (!DeviceIoControl(device,
- IOCTL_STORAGE_EJECT_MEDIA,
- NULL,
- 0,
- NULL,
- 0,
- &dw,
- NULL))
- if (force_dismount ? !ImDiskForceRemoveDevice(device, 0) : FALSE)
+ if (!DeviceIoControl(device,
+ IOCTL_STORAGE_EJECT_MEDIA,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &dw,
+ NULL))
+ {
+ if (force_dismount && !ImDiskForceRemoveDevice(device, 0))
+ {
+ if (hWnd != NULL)
{
- if (hWnd != NULL)
- MsgBoxLastError(hWnd, L"Error removing device:");
- NtClose(device);
- return FALSE;
+ MsgBoxLastError(hWnd, L"Error removing device:");
}
- DeviceIoControl(device,
- FSCTL_UNLOCK_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &dw,
- NULL);
+ NtClose(device);
+ return FALSE;
+ }
+ }
- NtClose(device);
+ DeviceIoControl(device,
+ FSCTL_UNLOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &dw,
+ NULL);
+
+ NtClose(device);
+
+ if (MountPoint != NULL)
+ {
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"Removing mount point...");
- if (MountPoint != NULL)
+ if (!ImDiskRemoveMountPoint(MountPoint))
{
if (hWnd != NULL)
- SetWindowText(hWnd, L"Removing mount point...");
-
- if (!ImDiskRemoveMountPoint(MountPoint))
{
- if (hWnd != NULL)
- {
- MsgBoxLastError(hWnd, L"Error removing drive letter:");
- }
+ MsgBoxLastError(hWnd, L"Error removing drive letter:");
}
}
+ }
- if (hWnd != NULL)
- SetWindowText(hWnd, L"OK.");
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"OK.");
- return TRUE;
+ return TRUE;
}
IMDISK_API BOOL
WINAPI
ImDiskForceRemoveDevice(HANDLE Device,
-DWORD DeviceNumber)
+ DWORD DeviceNumber)
{
UNICODE_STRING file_name;
HANDLE driver;
@@ -2249,8 +2387,10 @@ DWORD DeviceNumber)
}
RtlInitUnicodeString(&file_name, IMDISK_CTL_DEVICE_NAME);
+
driver = ImDiskOpenDeviceByName(&file_name,
GENERIC_READ | GENERIC_WRITE);
+
if (driver == NULL)
return FALSE;
@@ -2276,10 +2416,10 @@ DWORD DeviceNumber)
IMDISK_API BOOL
WINAPI
ImDiskChangeFlags(HWND hWnd,
-DWORD DeviceNumber,
-LPCWSTR MountPoint,
-DWORD FlagsToChange,
-DWORD Flags)
+ DWORD DeviceNumber,
+ LPCWSTR MountPoint,
+ DWORD FlagsToChange,
+ DWORD Flags)
{
HANDLE device;
DWORD dw;
@@ -2292,9 +2432,12 @@ DWORD Flags)
{
device = ImDiskOpenDeviceByNumber(DeviceNumber,
GENERIC_READ | GENERIC_WRITE);
+
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
+ }
}
else if ((wcslen(MountPoint) == 2) ? MountPoint[1] == ':' :
(wcslen(MountPoint) == 3) ? wcscmp(MountPoint + 1, L":\\") == 0 :
@@ -2310,16 +2453,21 @@ DWORD Flags)
NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if (device == INVALID_HANDLE_VALUE)
+ {
device = CreateFile(drive_letter_path,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ }
}
else
{
if (hWnd != NULL)
+ {
ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"ImDisk Virtual Disk Driver",
- L"Unsupported mount point: '%1'", MountPoint);
+ L"Unsupported mount point: '%1'", MountPoint);
+ }
+
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
@@ -2335,9 +2483,12 @@ DWORD Flags)
if (GetLastError() != NO_ERROR)
{
NtClose(device);
+
if (hWnd != NULL)
+ {
ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"ImDisk Virtual Disk Driver",
- L"Not an ImDisk Virtual Disk: '%1'", MountPoint);
+ L"Not an ImDisk Virtual Disk: '%1'", MountPoint);
+ }
return FALSE;
}
@@ -2358,6 +2509,7 @@ DWORD Flags)
0,
&dw,
NULL))
+ {
if (hWnd == NULL)
{
NtClose(device);
@@ -2376,6 +2528,7 @@ DWORD Flags)
return FALSE;
}
+ }
if (hWnd != NULL)
SetWindowText(hWnd, L"Dismounting filesystem...");
@@ -2388,6 +2541,7 @@ DWORD Flags)
0,
&dw,
NULL))
+ {
if (hWnd == NULL)
{
NtClose(device);
@@ -2404,6 +2558,7 @@ DWORD Flags)
return FALSE;
}
+ }
if (hWnd != NULL)
SetWindowText(hWnd, L"Setting device flags...");
@@ -2434,8 +2589,8 @@ DWORD Flags)
IMDISK_API BOOL
WINAPI
ImDiskExtendDevice(HWND hWnd,
-DWORD DeviceNumber,
-CONST PLARGE_INTEGER ExtendSize)
+ DWORD DeviceNumber,
+ CONST PLARGE_INTEGER ExtendSize)
{
HANDLE device;
DWORD dw;
@@ -2452,7 +2607,7 @@ CONST PLARGE_INTEGER ExtendSize)
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
if (device == INVALID_HANDLE_VALUE)
{
@@ -2493,10 +2648,11 @@ CONST PLARGE_INTEGER ExtendSize)
&dw, NULL))
{
if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
- L"An error occured when attempting to check the new total size of "
- L"the resized virtual disk:");
+ {
+ MsgBoxLastError(hWnd,
+ L"An error occurred when attempting to check the new total size of "
+ L"the resized virtual disk:");
+ }
NtClose(device);
return FALSE;
@@ -2511,10 +2667,11 @@ CONST PLARGE_INTEGER ExtendSize)
&dw, NULL))
{
if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
- L"An error occured when attempting to check the new total size of "
- L"the resized virtual disk:");
+ {
+ MsgBoxLastError(hWnd,
+ L"An error occurred when attempting to check the new total size of "
+ L"the resized virtual disk:");
+ }
NtClose(device);
return FALSE;
@@ -2531,12 +2688,15 @@ CONST PLARGE_INTEGER ExtendSize)
NULL,
0,
&dw, NULL))
+ {
if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
- L"The disk size was extended successfully, but it was not possible "
- L"to extend the current filesystem on it. You will have to reformat "
- L"the disk to use the full disk size.");
+ {
+ MsgBoxLastError(hWnd,
+ L"The disk size was extended successfully, but it was not possible "
+ L"to extend the current filesystem on it. You will have to reformat "
+ L"the disk to use the full disk size.");
+ }
+ }
NtClose(device);
return TRUE;
@@ -2545,9 +2705,9 @@ CONST PLARGE_INTEGER ExtendSize)
IMDISK_API BOOL
WINAPI
ImDiskSaveImageFile(IN HANDLE DeviceHandle,
-IN HANDLE FileHandle,
-IN DWORD BufferSize OPTIONAL,
-IN LPBOOL CancelFlag OPTIONAL)
+ IN HANDLE FileHandle,
+ IN DWORD BufferSize OPTIONAL,
+ IN LPBOOL CancelFlag OPTIONAL)
{
LPBYTE buffer;
IMDISK_SET_DEVICE_FLAGS device_flags = { 0 };
@@ -2648,7 +2808,7 @@ IN LPBOOL CancelFlag OPTIONAL)
IMDISK_API BOOL
WINAPI
ImDiskAdjustImageFileSize(IN HANDLE FileHandle,
-IN PLARGE_INTEGER FileSize)
+ IN PLARGE_INTEGER FileSize)
{
ULARGE_INTEGER existing_size = { 0 };
DWORD ptr;
@@ -2657,9 +2817,11 @@ IN PLARGE_INTEGER FileSize)
// original disk volume and possibly adjusts image file size if it does not
// exactly match the size of the original disk/partition.
existing_size.LowPart = GetFileSize(FileHandle, &existing_size.HighPart);
- if (existing_size.LowPart == INVALID_FILE_SIZE)
- if (GetLastError() != NO_ERROR)
- return FALSE;
+ if (existing_size.LowPart == INVALID_FILE_SIZE &&
+ GetLastError() != NO_ERROR)
+ {
+ return FALSE;
+ }
if (existing_size.QuadPart < (ULONGLONG)FileSize->QuadPart)
{
@@ -2671,9 +2833,12 @@ IN PLARGE_INTEGER FileSize)
FileSize->LowPart,
(LPLONG)&FileSize->HighPart,
FILE_BEGIN);
- if (ptr == INVALID_SET_FILE_POINTER)
- if (GetLastError() != NO_ERROR)
- return FALSE;
+
+ if (ptr == INVALID_SET_FILE_POINTER &&
+ GetLastError() != NO_ERROR)
+ {
+ return FALSE;
+ }
return SetEndOfFile(FileHandle);
}
@@ -2681,7 +2846,7 @@ IN PLARGE_INTEGER FileSize)
IMDISK_API BOOL
WINAPI
ImDiskGetVolumeSize(IN HANDLE Handle,
-IN OUT PLONGLONG Size)
+ IN OUT PLONGLONG Size)
{
PARTITION_INFORMATION partition_info = { 0 };
DISK_GEOMETRY disk_geometry = { 0 };
@@ -2732,8 +2897,8 @@ IN OUT PLONGLONG Size)
IMDISK_API BOOL
WINAPI
ImDiskGetFormattedGeometry(IN LPCWSTR ImageFile,
-IN PLARGE_INTEGER Offset OPTIONAL,
-IN OUT PDISK_GEOMETRY DiskGeometry)
+ IN PLARGE_INTEGER Offset OPTIONAL,
+ IN OUT PDISK_GEOMETRY DiskGeometry)
{
HANDLE hImageFile;
BOOL bResult;
@@ -2761,9 +2926,9 @@ IN OUT PDISK_GEOMETRY DiskGeometry)
IMDISK_API BOOL
WINAPI
ImDiskGetFormattedGeometryIndirect(IN HANDLE Handle,
-IN ImDiskReadFileProc ReadFileProc,
-IN PLARGE_INTEGER Offset OPTIONAL,
-IN OUT PDISK_GEOMETRY DiskGeometry)
+ IN ImDiskReadFileProc ReadFileProc,
+ IN PLARGE_INTEGER Offset OPTIONAL,
+ IN OUT PDISK_GEOMETRY DiskGeometry)
{
FAT_VBR fat_vbr;
LARGE_INTEGER offset = { 0 };
@@ -2787,10 +2952,10 @@ IN OUT PDISK_GEOMETRY DiskGeometry)
IMDISK_API BOOL
WINAPI
ImDiskBuildMBR(IN PDISK_GEOMETRY DiskGeometry OPTIONAL,
-IN PPARTITION_INFORMATION PartitionInformation OPTIONAL,
-IN BYTE NumberOfPartitions OPTIONAL,
-IN OUT LPBYTE MBR,
-IN DWORD_PTR MBRSize)
+ IN PPARTITION_INFORMATION PartitionInformation OPTIONAL,
+ IN BYTE NumberOfPartitions OPTIONAL,
+ IN OUT LPBYTE MBR,
+ IN DWORD_PTR MBRSize)
{
BYTE i;
@@ -2858,7 +3023,7 @@ IN DWORD_PTR MBRSize)
IMDISK_API DWORD
WINAPI
ImDiskConvertCHSToLBA(IN PDISK_GEOMETRY DiskGeometry,
-IN LPBYTE CHS)
+ IN LPBYTE CHS)
{
DWORD cylinder = (((DWORD)CHS[1] & 0xC0) << 2) | CHS[2];
DWORD heads = CHS[0];
@@ -2866,13 +3031,13 @@ IN LPBYTE CHS)
return
((cylinder * DiskGeometry->TracksPerCylinder + heads) *
- DiskGeometry->SectorsPerTrack) + sector - 1;
+ DiskGeometry->SectorsPerTrack) + sector - 1;
}
IMDISK_API DWORD
WINAPI
ImDiskConvertLBAToCHS(IN PDISK_GEOMETRY DiskGeometry,
-IN DWORD LBA)
+ IN DWORD LBA)
{
/*
cylinder = LBA / (heads_per_cylinder * sectors_per_track)
@@ -2897,8 +3062,8 @@ IN DWORD LBA)
temp %
DiskGeometry->SectorsPerTrack + 1;
- if ((cylinder >= 1024) |
- (head >= 256) |
+ if ((cylinder >= 1024) ||
+ (head >= 256) ||
(sector >= 64))
{
cylinder = 1023;
@@ -2915,12 +3080,16 @@ IN DWORD LBA)
IMDISK_API VOID
WINAPI
-ImDiskNativePathToWin32(IN OUT LPWSTR *Path)
+ImDiskNativePathToWin32(IN OUT LPWSTR* Path)
{
if ((Path == NULL) || (Path[0] == 0))
+ {
return;
+ }
else if (wcsncmp(*Path, L"\\??\\", 4) == 0)
+ {
(*Path)[1] = L'\\';
+ }
else if (wcsncmp(*Path, L"\\DosDevices\\", 12) == 0)
{
(*Path) += 8;
@@ -2929,10 +3098,14 @@ ImDiskNativePathToWin32(IN OUT LPWSTR *Path)
(*Path)[3] = L'?';
}
else
+ {
return;
+ }
- if ((*Path)[4] != 0 ? (*Path)[5] == L':' : FALSE)
+ if ((*Path)[4] != 0 && (*Path)[5] == L':')
+ {
(*Path) += 4;
+ }
else if (wcsncmp(*Path, L"\\\\?\\UNC\\", 8) == 0)
{
(*Path) += 6;
@@ -2947,16 +3120,23 @@ ImDiskOpenRefreshEvent(BOOL InheritHandle)
SECURITY_ATTRIBUTES sec_attrs = { 0 };
PSECURITY_DESCRIPTOR sec_descr = NULL;
HANDLE hEvent = NULL;
- WCHAR *objname;
+ WCHAR* objname;
HANDLE h = CreateFile(L"\\\\?\\Global", 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
if ((h == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
objname = IMDISK_REFRESH_EVENT_NAME;
+ }
else
+ {
objname = L"Global\\" IMDISK_REFRESH_EVENT_NAME;
+ }
if (h != INVALID_HANDLE_VALUE)
+ {
CloseHandle(h);
+ }
// Initialize a security descriptor.
sec_descr = (PSECURITY_DESCRIPTOR)
@@ -3028,21 +3208,29 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
&value_size);
if (err_code == ERROR_SUCCESS)
+ {
if (CreateData->DeviceNumber == IMDISK_AUTO_DEVICE_NUMBER)
{
CreateData->DeviceNumber = load_devices;
++load_devices;
}
else
+ {
load_devices = max(load_devices, CreateData->DeviceNumber + 1);
+ }
+ }
else
+ {
if (CreateData->DeviceNumber == IMDISK_AUTO_DEVICE_NUMBER)
{
CreateData->DeviceNumber = 0;
load_devices = 1;
}
else
+ {
load_devices = CreateData->DeviceNumber + 1;
+ }
+ }
err_code = RegSetValueEx(hkey,
IMDISK_CFG_LOAD_DEVICES_VALUE,
@@ -3060,6 +3248,7 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
value_name = ImDiskAllocPrintF(IMDISK_CFG_IMAGE_FILE_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3070,9 +3259,9 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
{
LPWSTR value_data =
ImDiskAllocPrintF(L"%1!.*ws!",
- (int)(CreateData->FileNameLength /
- sizeof(*CreateData->FileName)),
- CreateData->FileName);
+ (int)(CreateData->FileNameLength /
+ sizeof(*CreateData->FileName)),
+ CreateData->FileName);
if (value_data == NULL)
{
@@ -3097,12 +3286,15 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
value_name = ImDiskAllocPrintF(IMDISK_CFG_SIZE_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3126,12 +3318,15 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
value_name = ImDiskAllocPrintF(IMDISK_CFG_FLAGS_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3155,12 +3350,15 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
value_name = ImDiskAllocPrintF(IMDISK_CFG_DRIVE_LETTER_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3187,7 +3385,9 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
@@ -3216,7 +3416,9 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
@@ -3283,6 +3485,7 @@ ImDiskRemoveRegistrySettings(DWORD DeviceNumber)
value_name = ImDiskAllocPrintF(IMDISK_CFG_IMAGE_FILE_PREFIX L"%1!u!",
DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3295,6 +3498,7 @@ ImDiskRemoveRegistrySettings(DWORD DeviceNumber)
value_name = ImDiskAllocPrintF(IMDISK_CFG_SIZE_PREFIX L"%1!u!",
DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3384,3 +3588,40 @@ ImDiskGetRegistryAutoLoadDevices(LPDWORD LoadDevicesValue)
return TRUE;
}
+
+BOOL
+WINAPI
+ImDiskIsProcessElevated()
+{
+ HANDLE hToken;
+ TOKEN_ELEVATION elevation;
+ DWORD dwSize;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ {
+ return FALSE;
+ }
+
+ if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize))
+ {
+ DWORD dwerr = GetLastError();
+ CloseHandle(hToken);
+ SetLastError(dwerr);
+
+ switch (dwerr)
+ {
+ case ERROR_INVALID_FUNCTION:
+ case ERROR_INVALID_PARAMETER:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ CloseHandle(hToken);
+
+ SetLastError(NO_ERROR);
+
+ return elevation.TokenIsElevated;
+}
diff --git a/cpl/drvio.h b/cpl/drvio.h
index a17263a..6e0d8c2 100644
--- a/cpl/drvio.h
+++ b/cpl/drvio.h
@@ -2,17 +2,31 @@
extern "C" {
#endif
- INT_PTR
- CALLBACK
- StatusDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ INT_PTR
+ CALLBACK
+ StatusDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- INT_PTR
- CALLBACK
- NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ INT_PTR
+ CALLBACK
+ NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL
- WINAPI
- ImDiskInteractiveCheckSave(HWND hWnd, HANDLE device);
+ BOOL
+ WINAPI
+ ImDiskInteractiveCheckSave(HWND hWnd, HANDLE device);
+
+ LONG
+ WINAPI
+ ImDiskShowCPlAppletElevated(HWND hWnd);
+
+ VOID
+ WINAPI
+ ImDiskRelaunchElevated(HWND hWnd, LPCSTR DllFunction,
+ LPCSTR CommandLine, int nCmdShow);
+
+ VOID
+ WINAPI
+ ImDiskRelaunchElevatedW(HWND hWnd, LPCWSTR DllFunction,
+ LPCWSTR CommandLine, int nCmdShow);
/**
This function is a quick perror-style way of displaying an error message
@@ -25,7 +39,7 @@ extern "C" {
VOID
WINAPI
MsgBoxLastError(IN HWND hWndParent OPTIONAL,
- IN LPCWSTR Prefix);
+ IN LPCWSTR Prefix);
extern
ULONGLONG
diff --git a/cpl/i386/imdisk.exp b/cpl/i386/imdisk.exp
index 46a859e..ade5bf0 100644
Binary files a/cpl/i386/imdisk.exp and b/cpl/i386/imdisk.exp differ
diff --git a/cpl/i386/imdisk.lib b/cpl/i386/imdisk.lib
index 6179ab7..558f52d 100644
Binary files a/cpl/i386/imdisk.lib and b/cpl/i386/imdisk.lib differ
diff --git a/cpl/ia64/imdisk.exp b/cpl/ia64/imdisk.exp
index fc81975..7718b5b 100644
Binary files a/cpl/ia64/imdisk.exp and b/cpl/ia64/imdisk.exp differ
diff --git a/cpl/ia64/imdisk.lib b/cpl/ia64/imdisk.lib
index ff01976..c01d187 100644
Binary files a/cpl/ia64/imdisk.lib and b/cpl/ia64/imdisk.lib differ
diff --git a/cpl/imdisk.cpp b/cpl/imdisk.cpp
index 589f2c5..624d53f 100644
--- a/cpl/imdisk.cpp
+++ b/cpl/imdisk.cpp
@@ -2,7 +2,7 @@
Control Panel Applet for the ImDisk Virtual Disk Driver for
Windows NT/2000/XP.
-Copyright (C) 2007-2018 Olof Lagerkvist.
+Copyright (C) 2007-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -135,7 +135,7 @@ BOOL *lpTranslated
wcSize,
_countof(wcSize));
- if ((item_text_size == 0) |
+ if ((item_text_size == 0) ||
(item_text_size >= _countof(wcSize)))
{
if (lpTranslated != NULL)
@@ -183,7 +183,9 @@ LoadDeviceToList(HWND hWnd, int iDeviceNumber, bool SelectItem)
if (!QueryDosDevice(wcMountPoint, wcActualTarget,
_countof(wcActualTarget)))
+ {
wcMountPoint[0] = 0;
+ }
else
{
wcActualTarget[_countof(wcActualTarget) - 1] = 0;
@@ -198,7 +200,7 @@ LoadDeviceToList(HWND hWnd, int iDeviceNumber, bool SelectItem)
wcMountPoint[0] = 0;
}
- LVITEM lvi;
+ LVITEM lvi = { 0 };
lvi.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
lvi.iItem = 0;
lvi.iSubItem = 0;
@@ -237,7 +239,7 @@ LoadDeviceToList(HWND hWnd, int iDeviceNumber, bool SelectItem)
case IMDISK_TYPE_VM:
if (create_data->FileNameLength == 0)
{
- if ((IMDISK_TYPE(create_data->Flags) == IMDISK_TYPE_FILE) &
+ if ((IMDISK_TYPE(create_data->Flags) == IMDISK_TYPE_FILE) &&
(IMDISK_FILE_TYPE(create_data->Flags) ==
IMDISK_FILE_TYPE_AWEALLOC))
{
@@ -250,7 +252,7 @@ LoadDeviceToList(HWND hWnd, int iDeviceNumber, bool SelectItem)
break;
}
}
-
+
mem.ReAlloc(create_data->FileNameLength +
sizeof(*create_data->FileName), HEAP_GENERATE_EXCEPTIONS);
@@ -417,9 +419,11 @@ RefreshList(HWND hWnd, DWORD SelectDeviceNumber)
}
for (DWORD counter = 1; counter <= *device_list; counter++)
+ {
LoadDeviceToList(hWnd,
- device_list[counter],
- device_list[counter] == SelectDeviceNumber);
+ device_list[counter],
+ device_list[counter] == SelectDeviceNumber);
+ }
return true;
}
@@ -722,8 +726,8 @@ IN BOOL IsCdRomType)
BOOL use_original_file_name = FALSE;
LARGE_INTEGER save_offset = { 0 };
- if ((IMDISK_DEVICE_TYPE(create_data->Flags) == IMDISK_DEVICE_TYPE_HD) ?
- TRUE : !IsCdRomType)
+ if ((IMDISK_DEVICE_TYPE(create_data->Flags) == IMDISK_DEVICE_TYPE_HD) ||
+ !IsCdRomType)
{
INT_PTR i = DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_DLG_OPTIONS_SAVE),
@@ -884,12 +888,24 @@ IN BOOL IsCdRomType)
}
CloseHandle(hImage);
- ImDiskMsgBoxPrintF(hWnd, MB_ICONINFORMATION,
- L"ImDisk Virtual Disk Driver",
- L"Successfully saved the contents of drive '%1!c!:' to "
- L"image file '%2'.",
- create_data->DriveLetter ? create_data->DriveLetter : L' ',
- ofn.lpstrFile);
+
+ if (create_data->DriveLetter != 0)
+ {
+ ImDiskMsgBoxPrintF(hWnd, MB_ICONINFORMATION,
+ L"ImDisk Virtual Disk Driver",
+ L"Successfully saved the contents of drive '%1!c!:' to "
+ L"image file '%2'.",
+ create_data->DriveLetter,
+ ofn.lpstrFile);
+ }
+ else
+ {
+ ImDiskMsgBoxPrintF(hWnd, MB_ICONINFORMATION,
+ L"ImDisk Virtual Disk Driver",
+ L"Successfully saved drive contents to "
+ L"image file '%1'.",
+ ofn.lpstrFile);
+ }
}
BOOL
@@ -1170,11 +1186,15 @@ NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_COMMAND:
{
- if ((GetWindowTextLength(GetDlgItem(hWnd, IDC_EDT_IMAGEFILE)) > 0) |
+ if ((GetWindowTextLength(GetDlgItem(hWnd, IDC_EDT_IMAGEFILE)) > 0) ||
(GetDlgItemDouble(hWnd, IDC_EDT_SIZE, NULL) > 0))
+ {
EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
+ }
else
+ {
EnableWindow(GetDlgItem(hWnd, IDOK), FALSE);
+ }
if (GetWindowTextLength(GetDlgItem(hWnd, IDC_EDT_IMAGEFILE)) > 0)
{
@@ -1246,7 +1266,7 @@ NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
wcSize,
_countof(wcSize));
- if ((item_text_size == 0) |
+ if ((item_text_size == 0) ||
(item_text_size >= _countof(wcSize)))
{
MessageBox(hWnd,
@@ -1263,7 +1283,7 @@ NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
disk_geometry.Cylinders.QuadPart = wcstoul(wcSize, &stop_pos, 0);
// If failed, try to parse as double
- if ((stop_pos == wcSize) | (stop_pos[0] != 0))
+ if ((stop_pos == wcSize) || (stop_pos[0] != 0))
{
double size = wcstod(wcSize, &stop_pos);
@@ -1478,7 +1498,7 @@ ExtendDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM /*lParam*/)
wcSize,
_countof(wcSize));
- if ((item_text_size == 0) |
+ if ((item_text_size == 0) ||
(item_text_size >= _countof(wcSize)))
{
MessageBox(hWnd,
@@ -1804,6 +1824,7 @@ CPlAppletDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
DWORD device_number = (DWORD)
DialogBox(hInstance, MAKEINTRESOURCE(IDD_NEWDIALOG), hWnd,
NewDlgProc);
+
if (device_number != IMDISK_AUTO_DEVICE_NUMBER)
RefreshList(GetDlgItem(hWnd, IDC_LISTVIEW), device_number);
@@ -2087,7 +2108,7 @@ CPlAppletDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
SendDlgItemMessage(hWnd, IDC_LISTVIEW, LVM_GETITEM, 0,
(LPARAM)&lvi);
- if ((mount_point[0] < 'A') | (mount_point[0] > 'Z'))
+ if ((mount_point[0] < 'A') || (mount_point[0] > 'Z'))
{
ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"Unsupported mount point",
L"It is only possible to format drives with a "
@@ -2124,7 +2145,7 @@ CPlAppletDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
L"ImDisk Virtual Disk Driver for Windows NT/2000/XP/2003.\r\n"
L"Version %1!i!.%2!i!.%3!i! - (Compiled %4!hs!)\r\n"
L"\r\n"
- L"Copyright (C) 2004-2018 Olof Lagerkvist.\r\n"
+ L"Copyright (C) 2004-2021 Olof Lagerkvist.\r\n"
L"http://www.ltr-data.se olof@ltr-data.se\r\n"
L"\r\n"
L"Permission is hereby granted, free of charge, to any person\r\n"
@@ -2348,6 +2369,117 @@ ImDiskInteractiveCheckSave(HWND hWnd, HANDLE device)
}
}
+EXTERN_C
+VOID WINAPI
+ImDiskRelaunchElevated(HWND hWnd, LPCSTR DllFunction, LPCSTR CommandLine,
+ int nCmdShow)
+{
+ WHeapMem path(MAX_PATH, HEAP_GENERATE_EXCEPTIONS);
+
+ UINT length = GetSystemDirectoryA(path, (UINT)path.Count());
+
+ if (length == 0 || length >= path.Count())
+ {
+ ImDiskMsgBoxPrintF(hWnd, MB_ICONERROR, L"ImDisk Virtual Disk Driver",
+ L"Cannot find system directory.");
+
+ return;
+ }
+
+ strncat((LPSTR)path + length, "\\rundll32.exe",
+ path.Count() - length - 2);
+
+ WMem arguments(ImDiskAllocPrintFA("%1!s! %2!s!",
+ DllFunction, CommandLine));
+
+ if (arguments == NULL)
+ {
+ MsgBoxLastError(hWnd,
+ L"Not enough memory to launch ImDisk Control Panel applet with administrative privileges:");
+
+ return;
+ }
+
+ int inst = (int)(INT_PTR)ShellExecuteA(hWnd, "runas", path, arguments, NULL,
+ nCmdShow);
+
+ if (inst > 32)
+ {
+ return;
+ }
+
+ MsgBoxLastError(hWnd,
+ L"Failed to launch ImDisk Control Panel applet with administrative privileges:");
+
+ return;
+}
+
+EXTERN_C
+VOID WINAPI
+ImDiskRelaunchElevatedW(HWND hWnd, LPCWSTR DllFunction, LPCWSTR CommandLine,
+ int nCmdShow)
+{
+ WHeapMem path(MAX_PATH * sizeof(WCHAR), HEAP_GENERATE_EXCEPTIONS);
+
+ UINT length = GetSystemDirectory(path, (UINT)path.Count());
+
+ if (length == 0 || length >= path.Count())
+ {
+ ImDiskMsgBoxPrintF(hWnd, MB_ICONERROR, L"ImDisk Virtual Disk Driver",
+ L"Cannot find system directory.");
+
+ return;
+ }
+
+ wcsncat((LPWSTR)path + length, L"\\rundll32.exe",
+ path.Count() - length - 2);
+
+ WMem arguments(ImDiskAllocPrintF(L"%1!ws! %2!ws!",
+ DllFunction, CommandLine));
+
+ if (arguments == NULL)
+ {
+ MsgBoxLastError(hWnd,
+ L"Not enough memory to launch ImDisk Control Panel applet with administrative privileges:");
+
+ return;
+ }
+
+ int inst = (int)(INT_PTR)ShellExecute(hWnd, L"runas", path, arguments, NULL,
+ nCmdShow);
+
+ if (inst > 32)
+ {
+ return;
+ }
+
+ MsgBoxLastError(hWnd,
+ L"Failed to launch ImDisk Control Panel applet with administrative privileges:");
+
+ return;
+}
+
+EXTERN_C
+LONG WINAPI
+ImDiskShowCPlAppletElevated(HWND hwndCPl)
+{
+ if (!ImDiskIsProcessElevated())
+ {
+ ImDiskRelaunchElevatedW(hwndCPl, L"shell32.dll,Control_RunDLL",
+ L"imdisk.cpl", SW_SHOW);
+
+ return 0;
+ }
+
+ if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_CPLAPPLET), hwndCPl,
+ CPlAppletDlgProc) == -1)
+ {
+ MsgBoxLastError(hwndCPl, L"Failed to launch ImDisk Control Panel applet:");
+ }
+
+ return 0;
+}
+
EXTERN_C
IMDISK_API
LONG APIENTRY
@@ -2360,12 +2492,7 @@ LPARAM lParam2 // second message parameter
switch (uMsg)
{
case CPL_DBLCLK:
- if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_CPLAPPLET), hwndCPl,
- CPlAppletDlgProc) == -1)
- MsgBoxLastError(hwndCPl,
- L"Error loading dialog box:");
-
- return 0;
+ return ImDiskShowCPlAppletElevated(hwndCPl);
case CPL_EXIT:
return 0;
diff --git a/cpl/imdisk.rc b/cpl/imdisk.rc
index 9b3dfe8..5e1c848 100644
--- a/cpl/imdisk.rc
+++ b/cpl/imdisk.rc
@@ -37,7 +37,7 @@ FILESUBTYPE 0
VALUE "FileDescription", "Control Panel Applet for the ImDisk Virtual Disk Driver\0"
VALUE "FileVersion", IMDISK_RC_VERSION_STR ".59\0"
VALUE "InternalName", "imdisk\0"
- VALUE "LegalCopyright", "Copyright © 2004-2018 Olof Lagerkvist.\0"
+ VALUE "LegalCopyright", "Copyright © 2004-2021 Olof Lagerkvist.\0"
VALUE "OriginalFilename", "imdisk.cpl\0"
VALUE "ProductName", "imdisk\0"
VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".59\0"
diff --git a/cpl/mbr.c b/cpl/mbr.c
index 9472060..7428909 100644
--- a/cpl/mbr.c
+++ b/cpl/mbr.c
@@ -4,6 +4,8 @@
extern "C" {
#endif
+#ifdef INCLUDE_GPL_ORIGIN
+
const char default_mbr[] =
{
0xFA, 0xFC, 0x31, 0xC0, 0x8E, 0xD0, 0x8E, 0xD8, 0xBD, 0x00, 0x7C, 0x8D, 0x66, 0xE0, 0xFB, 0xB8,
@@ -40,7 +42,47 @@ extern "C" {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA,
};
- const unsigned int default_mbr_size = sizeof(default_mbr);
+#else // INCLUDE_GPL_ORIGIN
+
+ const char default_mbr[] =
+ {
+ 0xF4, 0xEB, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA
+ };
+
+#endif // INCLUDE_GPL_ORIGIN
+
+const unsigned int default_mbr_size = sizeof(default_mbr);
#ifdef __cplusplus
}
diff --git a/cpl/rundll.c b/cpl/rundll.c
index 13e06f9..316e23b 100644
--- a/cpl/rundll.c
+++ b/cpl/rundll.c
@@ -2,7 +2,7 @@
rundll32.exe compatible functions for the ImDisk Virtual Disk Driver for
Windows NT/2000/XP.
-Copyright (C) 2007-2018 Olof Lagerkvist.
+Copyright (C) 2007-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -55,6 +55,14 @@ HINSTANCE hInst,
LPWSTR lpszCmdLine,
int nCmdShow)
{
+ if (!ImDiskIsProcessElevated())
+ {
+ ImDiskRelaunchElevatedW(hWnd, L"imdisk.cpl,RunDLL_MountFile",
+ lpszCmdLine, nCmdShow);
+
+ return;
+ }
+
DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_NEWDIALOG), hWnd, NewDlgProc,
(LPARAM)lpszCmdLine);
}
@@ -70,6 +78,14 @@ int nCmdShow)
int file_name_length;
LPWSTR file_name;
+ if (!ImDiskIsProcessElevated())
+ {
+ ImDiskRelaunchElevated(hWnd, "imdisk.cpl,RunDLL_MountFile",
+ lpszCmdLine, nCmdShow);
+
+ return;
+ }
+
file_name_length = (int)(strlen(lpszCmdLine) + 1);
file_name = (LPWSTR)malloc(((size_t)file_name_length) << 1);
@@ -108,6 +124,14 @@ int nCmdShow)
WCHAR mount_point[3] = L" :";
HWND hWndStatus;
+ if (!ImDiskIsProcessElevated())
+ {
+ ImDiskRelaunchElevated(hWnd, "imdisk.cpl,RunDLL_RemoveDevice",
+ lpszCmdLine, nCmdShow);
+
+ return;
+ }
+
// If user right-clicked in Windows Explorer the drive we are dismounting is
// the current directory in this process. Change to Windows directory.
if (GetWindowsDirectory(win_dir, _countof(win_dir)))
@@ -150,6 +174,14 @@ int nCmdShow)
HANDLE hDev;
BOOL bIsCdRomType = FALSE;
+ if (!ImDiskIsProcessElevated())
+ {
+ ImDiskRelaunchElevated(hWnd, "imdisk.cpl,RunDLL_SaveImageFile",
+ lpszCmdLine, nCmdShow);
+
+ return;
+ }
+
switch (GetDriveTypeA(lpszCmdLine))
{
case DRIVE_CDROM:
diff --git a/cpl/sources b/cpl/sources
index 41a219d..0fb6fb5 100644
--- a/cpl/sources
+++ b/cpl/sources
@@ -2,7 +2,7 @@ TARGETNAME=imdisk
TARGETEXT=cpl
TARGETPATH=.
TARGETTYPE=DYNLINK
-C_DEFINES = $(C_DEFINES) /DUNICODE /D_UNICODE /DNT4_COMPATIBLE /DIMDISK_CPL_EXPORTS
+C_DEFINES = $(C_DEFINES) /DUNICODE /D_UNICODE /DNT4_COMPATIBLE /DIMDISK_CPL_EXPORTS /DINCLUDE_GPL_ORIGIN
UMTYPE=windows
USE_MSVCRT=1
MSC_OPTIMIZATION=/Ox /GF
diff --git a/cpl/sources.props b/cpl/sources.props
index 3aff5f7..d755d47 100644
--- a/cpl/sources.props
+++ b/cpl/sources.props
@@ -4,7 +4,7 @@
imdisk
cpl
DYNLINK
- $(C_DEFINES) /DUNICODE /D_UNICODE
+ $(C_DEFINES) /DUNICODE /D_UNICODE /DINCLUDE_GPL_ORIGIN
windows
1
/Ox /GF
diff --git a/cpl/wconmsg.cpp b/cpl/wconmsg.cpp
index c80714b..0a648d7 100644
--- a/cpl/wconmsg.cpp
+++ b/cpl/wconmsg.cpp
@@ -1,7 +1,7 @@
/*
No-GUI support for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.
-Copyright (C) 2007-2018 Olof Lagerkvist.
+Copyright (C) 2007-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/cplcore/Icons/CD.bmp b/cplcore/Icons/CD.bmp
new file mode 100644
index 0000000..4b57347
Binary files /dev/null and b/cplcore/Icons/CD.bmp differ
diff --git a/cplcore/Icons/CD.ico b/cplcore/Icons/CD.ico
new file mode 100644
index 0000000..d0b3dae
Binary files /dev/null and b/cplcore/Icons/CD.ico differ
diff --git a/cplcore/Icons/Disk.ico b/cplcore/Icons/Disk.ico
new file mode 100644
index 0000000..250b36e
Binary files /dev/null and b/cplcore/Icons/Disk.ico differ
diff --git a/cplcore/Icons/Floppy.ico b/cplcore/Icons/Floppy.ico
new file mode 100644
index 0000000..3813631
Binary files /dev/null and b/cplcore/Icons/Floppy.ico differ
diff --git a/cplcore/Icons/VD.ico b/cplcore/Icons/VD.ico
new file mode 100644
index 0000000..558a8bd
Binary files /dev/null and b/cplcore/Icons/VD.ico differ
diff --git a/cplcore/Icons/VDInfo.ico b/cplcore/Icons/VDInfo.ico
new file mode 100644
index 0000000..1fbe0de
Binary files /dev/null and b/cplcore/Icons/VDInfo.ico differ
diff --git a/cplcore/amd64/imdisk.exp b/cplcore/amd64/imdisk.exp
index 3b8479d..aacbd82 100644
Binary files a/cplcore/amd64/imdisk.exp and b/cplcore/amd64/imdisk.exp differ
diff --git a/cplcore/amd64/imdisk.lib b/cplcore/amd64/imdisk.lib
index 7ba8c65..d65e6bc 100644
Binary files a/cplcore/amd64/imdisk.lib and b/cplcore/amd64/imdisk.lib differ
diff --git a/cplcore/cplcore.inf b/cplcore/cplcore.inf
new file mode 100644
index 0000000..fabaf8b
--- /dev/null
+++ b/cplcore/cplcore.inf
@@ -0,0 +1,54 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = cplcore.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk Virtual Disk Driver API library"
+
+
+[SourceDisksFiles.x86]
+imdisk.cpl = 1, i386
+
+[SourceDisksFiles.ia64]
+imdisk.cpl = 1, ia64
+
+[SourceDisksFiles.amd64]
+imdisk.cpl = 1, amd64
+
+[SourceDisksFiles.arm]
+imdisk.cpl = 1, arm
+
+[SourceDisksFiles.arm64]
+imdisk.cpl = 1, arm64
+
+[DestinationDirs]
+ImDiskCplExeFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ImDiskCplExeFiles
+
+
+[ImDiskCplExeFiles]
+imdisk.cpl
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDiskCpl, , ImDiskCpl
+
+
+[ImDiskCpl]
+DisplayName = "ImDisk Virtual Disk Driver API library"
+StartType = 2
+ServiceType = 16
+ErrorControl = 0
+ServiceBinary = %11%\imdisk.cpl
diff --git a/cplcore/cplcore.vcxproj b/cplcore/cplcore.vcxproj
index 474fd4d..d036a2c 100644
--- a/cplcore/cplcore.vcxproj
+++ b/cplcore/cplcore.vcxproj
@@ -355,16 +355,21 @@
-
+
+
+
+
-
+
+
+
diff --git a/cplcore/drvio.c b/cplcore/drvio.c
index fea242f..ebcf076 100644
--- a/cplcore/drvio.c
+++ b/cplcore/drvio.c
@@ -1,7 +1,7 @@
/*
API library for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.
-Copyright (C) 2007-2018 Olof Lagerkvist.
+Copyright (C) 2007-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -54,7 +54,7 @@ typedef struct _KNOWN_FORMAT
{
LPCWSTR Extension;
LONGLONG Offset;
-} KNOWN_FORMAT, *PKNOWN_FORMAT;
+} KNOWN_FORMAT, * PKNOWN_FORMAT;
KNOWN_FORMAT KnownFormats[] = {
{ L"nrg", 600 << 9 },
@@ -67,7 +67,7 @@ ImDiskFlushWindowMessages(HWND hWnd)
{
#ifndef CORE_BUILD
MSG msg;
-
+
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
if (!IsDialogMessage(hWnd, &msg))
@@ -99,6 +99,25 @@ ImDiskAllocPrintF(LPCWSTR lpMessage, ...)
return lpBuf;
}
+IMDISK_API LPSTR
+CDECL
+ImDiskAllocPrintFA(LPCSTR lpMessage, ...)
+{
+ va_list param_list;
+ LPSTR lpBuf = NULL;
+
+ va_start(param_list, lpMessage);
+
+ if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_STRING, lpMessage, 0, 0,
+ (LPSTR)&lpBuf, 0, ¶m_list))
+ {
+ return NULL;
+ }
+
+ return lpBuf;
+}
+
ULONGLONG APIFlags;
IMDISK_API ULONGLONG
@@ -200,8 +219,8 @@ MsgBoxLastError(HWND hWnd, LPCWSTR Prefix)
IMDISK_API VOID
WINAPI
ImDiskGetPartitionTypeName(IN BYTE PartitionType,
-IN OUT LPWSTR Name,
-IN DWORD NameSize)
+ IN OUT LPWSTR Name,
+ IN DWORD NameSize)
{
LPWSTR name;
WCHAR other_type[] = L"Type XXh";
@@ -278,7 +297,7 @@ IN DWORD NameSize)
IMDISK_API BOOL
WINAPI
ImDiskGetOffsetByFileExt(IN LPCWSTR ImageFile,
-IN OUT PLARGE_INTEGER Offset)
+ IN OUT PLARGE_INTEGER Offset)
{
LPCWSTR path_sep;
PKNOWN_FORMAT known_format;
@@ -299,12 +318,14 @@ IN OUT PLARGE_INTEGER Offset)
for (known_format = KnownFormats;
known_format <
KnownFormats + _countof(KnownFormats);
- known_format++)
+ known_format++)
+ {
if (_wcsicmp(ImageFile, known_format->Extension) == 0)
{
Offset->QuadPart = known_format->Offset;
return TRUE;
}
+ }
return FALSE;
}
@@ -406,7 +427,7 @@ ImDiskGetPartitionInformation(IN LPCWSTR ImageFile,
return bResult;
}
-typedef BOOL(WINAPI *ImDiskReadFileProc)(IN HANDLE Handle,
+typedef BOOL(WINAPI* ImDiskReadFileProc)(IN HANDLE Handle,
IN OUT LPVOID Buffer,
IN LARGE_INTEGER Offset,
IN DWORD NumberOfBytesToRead,
@@ -415,15 +436,17 @@ typedef BOOL(WINAPI *ImDiskReadFileProc)(IN HANDLE Handle,
IMDISK_API BOOL
WINAPI
ImDiskReadFileHandle(IN HANDLE Handle,
-IN OUT LPVOID Buffer,
-IN LARGE_INTEGER Offset,
-IN DWORD NumberOfBytesToRead,
-IN OUT LPDWORD NumberOfBytesRead)
+ IN OUT LPVOID Buffer,
+ IN LARGE_INTEGER Offset,
+ IN DWORD NumberOfBytesToRead,
+ IN OUT LPDWORD NumberOfBytesRead)
{
if (SetFilePointer(Handle, Offset.LowPart, &Offset.HighPart,
- FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- if (GetLastError() != NO_ERROR)
- return FALSE;
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER &&
+ GetLastError() != NO_ERROR)
+ {
+ return FALSE;
+ }
return ReadFile(Handle,
Buffer,
@@ -613,7 +636,7 @@ typedef struct _IMDISKGETPARTITIONINFOINDIRECTEX_DATA
{
PPARTITION_INFORMATION Next;
DWORD Count;
-} IMDISKGETPARTITIONINFOINDIRECTEX_DATA, *PIMDISKGETPARTITIONINFOINDIRECTEX_DATA;
+} IMDISKGETPARTITIONINFOINDIRECTEX_DATA, * PIMDISKGETPARTITIONINFOINDIRECTEX_DATA;
BOOL CALLBACK
GotPartInfoForArray(LPVOID UserData, PPARTITION_INFORMATION PartitionInformation)
@@ -696,11 +719,11 @@ ImDiskGetSinglePartitionInfoIndirect(IN HANDLE Handle,
IMDISK_API BOOL
WINAPI
ImDiskGetPartitionInfoIndirect(IN HANDLE Handle,
-IN ImDiskReadFileProc ReadFileProc,
-IN DWORD SectorSize OPTIONAL,
-IN PLARGE_INTEGER Offset OPTIONAL,
-IN OUT PPARTITION_INFORMATION
-PartitionInformation)
+ IN ImDiskReadFileProc ReadFileProc,
+ IN DWORD SectorSize OPTIONAL,
+ IN PLARGE_INTEGER Offset OPTIONAL,
+ IN OUT PPARTITION_INFORMATION
+ PartitionInformation)
{
LPBYTE buffer = NULL;
DWORD read_size = 0;
@@ -802,7 +825,7 @@ PartitionInformation)
IMDISK_API BOOL
WINAPI
ImDiskImageContainsISOFS(IN LPCWSTR ImageFile,
-IN PLARGE_INTEGER Offset OPTIONAL)
+ IN PLARGE_INTEGER Offset OPTIONAL)
{
HANDLE hImageFile;
BOOL bResult;
@@ -829,8 +852,8 @@ IN PLARGE_INTEGER Offset OPTIONAL)
IMDISK_API BOOL
WINAPI
ImDiskImageContainsISOFSIndirect(IN HANDLE Handle,
-IN ImDiskReadFileProc ReadFileProc,
-IN PLARGE_INTEGER Offset OPTIONAL)
+ IN ImDiskReadFileProc ReadFileProc,
+ IN PLARGE_INTEGER Offset OPTIONAL)
{
const char magic[] = { 0x01, 'C', 'D', '0', '0', '1', 0x01 };
char buffer[sizeof(magic)];
@@ -922,7 +945,7 @@ typedef struct _REPARSE_DATA_JUNCTION
WORD DisplayNameOffset;
WORD DisplayNameLength;
BYTE Data[65536];
-} REPARSE_DATA_JUNCTION, *PREPARSE_DATA_JUNCTION;
+} REPARSE_DATA_JUNCTION, * PREPARSE_DATA_JUNCTION;
IMDISK_API BOOL
WINAPI
@@ -939,8 +962,14 @@ ImDiskCreateMountPoint(LPCWSTR MountPoint, LPCWSTR Target)
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer) + iSize +
2 + iSize + 2;
- if ((wcslen(MountPoint) == 2) &&
- (MountPoint[1] == L':'))
+ if (MountPoint == NULL || MountPoint[0] == 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if ((wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
{
WCHAR GlobalMountPoint[] = L"Global\\ :";
DWORD ddd_flags = DDD_RAW_TARGET_PATH;
@@ -953,7 +982,7 @@ ImDiskCreateMountPoint(LPCWSTR MountPoint, LPCWSTR Target)
ddd_flags |= DDD_NO_BROADCAST_SYSTEM;
}
-#ifdef _WIN64
+#ifndef _M_IX86
if (DefineDosDevice(ddd_flags, GlobalMountPoint, Target))
return TRUE;
@@ -987,20 +1016,20 @@ ImDiskCreateMountPoint(LPCWSTR MountPoint, LPCWSTR Target)
if (hDir == INVALID_HANDLE_VALUE)
return FALSE;
- if ((iSize + 6 > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) | (iSize == 0))
+ if ((iSize + 6 > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) || (iSize == 0))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- ReparseData = HeapAlloc(GetProcessHeap(),
+ ReparseData = (PREPARSE_DATA_BUFFER)HeapAlloc(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
buffer_size);
__analysis_assume(ReparseData != NULL);
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
-
+
ReparseData->ReparseDataLength = data_length;
ReparseData->MountPointReparseBuffer.SubstituteNameLength = (WORD)iSize;
@@ -1043,8 +1072,14 @@ ImDiskRemoveMountPoint(LPCWSTR MountPoint)
HANDLE hDir;
DWORD dw;
- if (((wcslen(MountPoint) == 2) && MountPoint[1] == ':') ||
- ((wcslen(MountPoint) == 3) && (wcscmp(MountPoint + 1, L":\\") == 0)))
+ if (MountPoint == NULL || MountPoint[0] == 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if ((wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
{
DWORD_PTR dwp;
DEV_BROADCAST_VOLUME dev_broadcast_volume = {
@@ -1070,7 +1105,7 @@ ImDiskRemoveMountPoint(LPCWSTR MountPoint)
SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, MountPoint, NULL);
#endif
}
-#ifndef _WIN64
+#ifdef _M_IX86
else if (!IMDISK_GTE_WIN2K())
{
}
@@ -1218,7 +1253,7 @@ ImDiskOpenDeviceByMountPoint(LPCWSTR MountPoint, DWORD AccessMode)
if ((MountPoint[0] != 0) &&
((wcscmp(MountPoint + 1, L":") == 0) ||
- (wcscmp(MountPoint + 1, L":\\") == 0)))
+ (wcscmp(MountPoint + 1, L":\\") == 0)))
{
DriveLetterPath[12] = MountPoint[0];
@@ -1248,7 +1283,7 @@ ImDiskOpenDeviceByMountPoint(LPCWSTR MountPoint, DWORD AccessMode)
if (hDir == INVALID_HANDLE_VALUE)
return INVALID_HANDLE_VALUE;
- ReparseData = HeapAlloc(GetProcessHeap(),
+ ReparseData = (PREPARSE_DATA_BUFFER)HeapAlloc(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
buffer_size);
@@ -1275,14 +1310,14 @@ ImDiskOpenDeviceByMountPoint(LPCWSTR MountPoint, DWORD AccessMode)
DeviceName.Length =
ReparseData->MountPointReparseBuffer.SubstituteNameLength;
-
+
DeviceName.Buffer = (PWSTR)
((PUCHAR)ReparseData->MountPointReparseBuffer.PathBuffer +
- ReparseData->MountPointReparseBuffer.SubstituteNameOffset);
-
+ ReparseData->MountPointReparseBuffer.SubstituteNameOffset);
+
DeviceName.MaximumLength = DeviceName.Length;
}
-
+
if (DeviceName.Buffer[(DeviceName.Length >> 1) - 1] == L'\\')
{
DeviceName.Buffer[(DeviceName.Length >> 1) - 1] = 0;
@@ -1309,7 +1344,9 @@ ImDiskCheckDriverVersion(HANDLE Device)
NULL, 0,
&VersionCheck, sizeof VersionCheck,
&BytesReturned, NULL))
+ {
return FALSE;
+ }
SetLastError(NO_ERROR);
@@ -1325,7 +1362,7 @@ ImDiskCheckDriverVersion(HANDLE Device)
IMDISK_API BOOL
WINAPI
ImDiskGetVersion(PULONG LibraryVersion,
-PULONG DriverVersion)
+ PULONG DriverVersion)
{
if (LibraryVersion != NULL)
*LibraryVersion = IMDISK_VERSION;
@@ -1380,9 +1417,14 @@ ImDiskFindFreeDriveLetter()
{
DWORD logical_drives = GetLogicalDrives();
WCHAR search;
+
for (search = L'D'; search <= L'Z'; search++)
+ {
if ((logical_drives & (1 << (search - L'A'))) == 0)
+ {
return search;
+ }
+ }
return 0;
}
@@ -1420,7 +1462,7 @@ ImDiskGetDeviceList()
IMDISK_API BOOL
WINAPI
ImDiskGetDeviceListEx(IN ULONG ListLength,
-OUT ULONG *DeviceList)
+ OUT ULONG* DeviceList)
{
UNICODE_STRING file_name;
HANDLE driver;
@@ -1446,7 +1488,7 @@ OUT ULONG *DeviceList)
NtClose(driver);
- if ((dw == sizeof(ULONG)) &
+ if ((dw == sizeof(ULONG)) &&
(*DeviceList > 0))
{
SetLastError(ERROR_MORE_DATA);
@@ -1460,8 +1502,8 @@ OUT ULONG *DeviceList)
IMDISK_API BOOL
WINAPI
ImDiskQueryDevice(DWORD DeviceNumber,
-PIMDISK_CREATE_DATA CreateData,
-ULONG CreateDataSize)
+ PIMDISK_CREATE_DATA CreateData,
+ ULONG CreateDataSize)
{
HANDLE device = ImDiskOpenDeviceByNumber(DeviceNumber, FILE_READ_ATTRIBUTES);
DWORD dw;
@@ -1495,12 +1537,12 @@ ULONG CreateDataSize)
IMDISK_API BOOL
WINAPI
ImDiskCreateDevice(HWND hWnd,
-PDISK_GEOMETRY DiskGeometry,
-PLARGE_INTEGER ImageOffset,
-DWORD Flags,
-LPCWSTR FileName,
-BOOL NativePath,
-LPWSTR MountPoint)
+ PDISK_GEOMETRY DiskGeometry,
+ PLARGE_INTEGER ImageOffset,
+ DWORD Flags,
+ LPCWSTR FileName,
+ BOOL NativePath,
+ LPWSTR MountPoint)
{
return ImDiskCreateDeviceEx(hWnd,
NULL,
@@ -1515,13 +1557,13 @@ LPWSTR MountPoint)
IMDISK_API BOOL
WINAPI
ImDiskCreateDeviceEx(HWND hWnd,
-LPDWORD DeviceNumber,
-PDISK_GEOMETRY DiskGeometry,
-PLARGE_INTEGER ImageOffset,
-DWORD Flags,
-LPCWSTR FileName,
-BOOL NativePath,
-LPWSTR MountPoint)
+ LPDWORD DeviceNumber,
+ PDISK_GEOMETRY DiskGeometry,
+ PLARGE_INTEGER ImageOffset,
+ DWORD Flags,
+ LPCWSTR FileName,
+ BOOL NativePath,
+ LPWSTR MountPoint)
{
PIMDISK_CREATE_DATA create_data;
UNICODE_STRING file_name;
@@ -1554,37 +1596,49 @@ LPWSTR MountPoint)
if (!ImDiskStartService(IMDISK_DRIVER_NAME))
switch (GetLastError())
- {
+ {
case ERROR_SERVICE_DOES_NOT_EXIST:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The ImDisk Virtual Disk Driver is not installed. "
- L"Please re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The ImDisk Virtual Disk Driver is not installed. "
+ L"Please re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"Cannot load imdisk.sys. "
- L"Please re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"Cannot load imdisk.sys. "
+ L"Please re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
case ERROR_SERVICE_DISABLED:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The ImDisk Virtual Disk Driver is disabled.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The ImDisk Virtual Disk Driver is disabled.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
default:
if (hWnd != NULL)
+ {
MsgBoxLastError(hWnd,
- L"Error loading ImDisk Virtual Disk Driver:");
+ L"Error loading ImDisk Virtual Disk Driver:");
+ }
+
return FALSE;
- }
+ }
ImDiskFlushWindowMessages(NULL);
@@ -1595,24 +1649,27 @@ LPWSTR MountPoint)
if (!ImDiskCheckDriverVersion(driver))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The version of the ImDisk Virtual Disk Driver "
- L"(imdisk.sys) installed on this system does not match "
- L"the version of this control program. Please reinstall "
- L"ImDisk to make sure that all components of it on this "
- L"system are from the same install package. You may have "
- L"to restart your computer if you still see this message "
- L"after reinstalling.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The version of the ImDisk Virtual Disk Driver "
+ L"(imdisk.sys) installed on this system does not match "
+ L"the version of this control program. Please reinstall "
+ L"ImDisk to make sure that all components of it on this "
+ L"system are from the same install package. You may have "
+ L"to restart your computer if you still see this message "
+ L"after reinstalling.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
// Physical memory allocation requires the AWEAlloc driver.
- if (((IMDISK_TYPE(Flags) == IMDISK_TYPE_FILE) |
- (IMDISK_TYPE(Flags) == 0)) &
+ if (((IMDISK_TYPE(Flags) == IMDISK_TYPE_FILE) ||
+ (IMDISK_TYPE(Flags) == 0)) &&
(IMDISK_FILE_TYPE(Flags) == IMDISK_FILE_TYPE_AWEALLOC))
{
HANDLE awealloc;
@@ -1643,26 +1700,35 @@ LPWSTR MountPoint)
{
case ERROR_SERVICE_DOES_NOT_EXIST:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The AWEAlloc driver is not installed. Please "
- L"re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The AWEAlloc driver is not installed. Please "
+ L"re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
break;
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"Cannot load the AWEAlloc driver. Please "
- L"re-install ImDisk.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"Cannot load the AWEAlloc driver. Please "
+ L"re-install ImDisk.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
break;
case ERROR_SERVICE_DISABLED:
if (hWnd != NULL)
+ {
MessageBox(hWnd,
- L"The AWEAlloc driver is disabled.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"The AWEAlloc driver is disabled.",
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
break;
default:
@@ -1675,93 +1741,119 @@ LPWSTR MountPoint)
}
}
// Proxy reconnection types requires the user mode service.
- else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &
- ((IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_TCP) |
- (IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_COMM)))
+ else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &&
+ ((IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_TCP) ||
+ (IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_COMM)))
{
- if (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- if (ImDiskStartService(IMDPROXY_SVC))
+ if (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0) &&
+ GetLastError() == ERROR_FILE_NOT_FOUND)
+ {
+ if (ImDiskStartService(IMDPROXY_SVC))
+ {
+ while (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
{
- while (!WaitNamedPipe(IMDPROXY_SVC_PIPE_DOSDEV_NAME, 0))
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- Sleep(500);
- else
- break;
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ Sleep(500);
+ else
+ break;
+ }
- if (hWnd != NULL)
- SetWindowText
- (hWnd,
+ if (hWnd != NULL)
+ {
+ SetWindowText(hWnd,
L"ImDisk Virtual Disk Driver Helper Service started.");
}
- else
+ }
+ else
+ {
+ switch (GetLastError())
{
- switch (GetLastError())
+ case ERROR_SERVICE_DOES_NOT_EXIST:
+ if (hWnd != NULL)
{
- case ERROR_SERVICE_DOES_NOT_EXIST:
- if (hWnd != NULL)
- MessageBox(hWnd,
+ MessageBox(hWnd,
L"The ImDisk Virtual Disk Driver Helper "
L"Service is not installed. Please re-install "
L"ImDisk.",
L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
- break;
+ }
+
+ break;
- case ERROR_PATH_NOT_FOUND:
- case ERROR_FILE_NOT_FOUND:
- if (hWnd != NULL)
- MessageBox(hWnd,
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_FILE_NOT_FOUND:
+ if (hWnd != NULL)
+ {
+ MessageBox(hWnd,
L"Cannot start the ImDisk Virtual Disk Driver "
L"Helper Service. Please re-install ImDisk.",
L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
- break;
+ }
+
+ break;
- case ERROR_SERVICE_DISABLED:
- if (hWnd != NULL)
- MessageBox(hWnd,
+ case ERROR_SERVICE_DISABLED:
+ if (hWnd != NULL)
+ {
+ MessageBox(hWnd,
L"The ImDisk Virtual Disk Driver Helper "
L"Service is disabled.",
L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
- break;
+ }
+
+ break;
- default:
- if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
+ default:
+ if (hWnd != NULL)
+ {
+ MsgBoxLastError(hWnd,
L"Error starting ImDisk Virtual Disk Driver Helper "
L"Service:");
}
-
- NtClose(driver);
- return FALSE;
}
+
+ NtClose(driver);
+ return FALSE;
+ }
+ }
}
if (FileName == NULL)
+ {
RtlInitUnicodeString(&file_name, NULL);
+ }
else if (NativePath)
{
if (!RtlCreateUnicodeString(&file_name, FileName))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd, L"Memory allocation error.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
}
}
- else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &
+ else if ((IMDISK_TYPE(Flags) == IMDISK_TYPE_PROXY) &&
(IMDISK_PROXY_TYPE(Flags) == IMDISK_PROXY_TYPE_SHM))
{
LPWSTR namespace_prefix;
LPWSTR prefixed_name;
HANDLE h = CreateFile(L"\\\\?\\Global", 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if ((h == INVALID_HANDLE_VALUE) &
+
+ if ((h == INVALID_HANDLE_VALUE) &&
(GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
namespace_prefix = L"\\BaseNamedObjects\\";
+ }
else
+ {
namespace_prefix = L"\\BaseNamedObjects\\Global\\";
+ }
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
@@ -1775,9 +1867,13 @@ LPWSTR MountPoint)
if (!RtlCreateUnicodeString(&file_name, prefixed_name))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd, L"Memory allocation error.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
}
}
@@ -1786,9 +1882,13 @@ LPWSTR MountPoint)
if (!RtlDosPathNameToNtPathName_U(FileName, &file_name, NULL, NULL))
{
NtClose(driver);
+
if (hWnd != NULL)
+ {
MessageBox(hWnd, L"Memory allocation error.",
- L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ L"ImDisk Virtual Disk Driver", MB_ICONSTOP);
+ }
+
return FALSE;
}
}
@@ -1803,7 +1903,7 @@ LPWSTR MountPoint)
// Check if mount point is a drive letter or junction point
if ((MountPoint != NULL) && (MountPoint[0] != 0) &&
((wcscmp(MountPoint + 1, L":") == 0) ||
- ((wcscmp(MountPoint + 1, L":\\") == 0))))
+ ((wcscmp(MountPoint + 1, L":\\") == 0))))
{
create_data->DriveLetter = MountPoint[0];
}
@@ -1860,10 +1960,14 @@ LPWSTR MountPoint)
IMDISK_DEVICE_BASE_NAME L"%u", create_data->DeviceNumber);
device_path[_countof(device_path) - 1] = 0;
- if ((wcslen(MountPoint) == 2) &&
- (MountPoint[1] == L':'))
+ if (MountPoint != NULL && MountPoint[0] != 0 &&
+ (wcscmp(MountPoint + 1, L":") == 0 ||
+ wcscmp(MountPoint + 1, L":\\") == 0))
{
-#ifndef _WIN64
+ WCHAR drive_letter[] = L" :";
+ drive_letter[0] = MountPoint[0];
+
+#ifdef _M_IX86
if (!IMDISK_GTE_WINXP())
{
DWORD ddd_flags = DDD_RAW_TARGET_PATH;
@@ -1874,18 +1978,21 @@ LPWSTR MountPoint)
ddd_flags |= DDD_NO_BROADCAST_SYSTEM;
}
- if (!DefineDosDevice(ddd_flags, MountPoint, device_path))
+ if (!DefineDosDevice(ddd_flags, drive_letter, device_path))
+ {
if (hWnd != NULL)
MsgBoxLastError(hWnd, L"Error creating mount point:");
+ }
}
#endif
if (hWnd != NULL)
- SetWindowText
- (hWnd,
- L"Notifying applications that device has been created...");
+ {
+ SetWindowText(hWnd,
+ L"Notifying applications that device has been created...");
+ }
- ImDiskNotifyShellDriveLetter(hWnd, MountPoint);
+ ImDiskNotifyShellDriveLetter(hWnd, drive_letter);
}
else
{
@@ -1899,10 +2006,11 @@ LPWSTR MountPoint)
IMDISK_API BOOL
WINAPI
ImDiskNotifyShellDriveLetter(HWND hWnd,
-LPWSTR DriveLetterPath)
+ LPWSTR DriveLetterPath)
{
#ifndef CORE_BUILD
DWORD_PTR dwp;
+
DEV_BROADCAST_VOLUME dev_broadcast_volume = {
sizeof(DEV_BROADCAST_VOLUME),
DBT_DEVTYP_VOLUME
@@ -1945,19 +2053,20 @@ LPWSTR DriveLetterPath)
4000,
&dwp);
- /* Tried PostMessage instead of SendMessageTimeout
+#if 0 // Tried PostMessage instead of SendMessageTimeout
PostMessage(HWND_BROADCAST,
- WM_DEVICECHANGE,
- DBT_DEVICEARRIVAL,
- (LPARAM)&dev_broadcast_volume);
+ WM_DEVICECHANGE,
+ DBT_DEVICEARRIVAL,
+ (LPARAM)&dev_broadcast_volume);
dev_broadcast_volume.dbcv_flags = DBTF_MEDIA;
PostMessage(HWND_BROADCAST,
- WM_DEVICECHANGE,
- DBT_DEVICEARRIVAL,
- (LPARAM)&dev_broadcast_volume);
- */
+ WM_DEVICECHANGE,
+ DBT_DEVICEARRIVAL,
+ (LPARAM)&dev_broadcast_volume);
+#endif
+
#endif
return TRUE;
@@ -1966,17 +2075,19 @@ LPWSTR DriveLetterPath)
IMDISK_API BOOL
WINAPI
ImDiskNotifyRemovePending(HWND hWnd,
-WCHAR DriveLetter)
+ WCHAR DriveLetter)
{
#ifndef CORE_BUILD
DEV_BROADCAST_VOLUME dev_broadcast_volume = {
sizeof(DEV_BROADCAST_VOLUME),
DBT_DEVTYP_VOLUME
};
+
DWORD_PTR dwp;
dev_broadcast_volume.dbcv_unitmask = 1 << (DriveLetter - L'A');
+#ifdef SEND_DBT_DEVICEQUERYREMOVE
SendMessageTimeout(HWND_BROADCAST,
WM_DEVICECHANGE,
DBT_DEVICEQUERYREMOVE,
@@ -1984,6 +2095,7 @@ WCHAR DriveLetter)
SMTO_BLOCK | SMTO_ABORTIFHUNG,
4000,
&dwp);
+#endif
SendMessageTimeout(HWND_BROADCAST,
WM_DEVICECHANGE,
@@ -2000,8 +2112,8 @@ WCHAR DriveLetter)
IMDISK_API BOOL
WINAPI
ImDiskRemoveDevice(HWND hWnd,
-DWORD DeviceNumber,
-LPCWSTR MountPoint)
+ DWORD DeviceNumber,
+ LPCWSTR MountPoint)
{
HANDLE device;
DWORD dw;
@@ -2017,11 +2129,11 @@ LPCWSTR MountPoint)
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- FILE_READ_ATTRIBUTES);
+ FILE_READ_ATTRIBUTES);
}
else if ((wcscmp(MountPoint + 1, L":") == 0) ||
(wcscmp(MountPoint + 1, L":\\") == 0))
@@ -2030,13 +2142,14 @@ LPCWSTR MountPoint)
drive_letter_path[4] = MountPoint[0];
// Notify processes that this device is about to be removed.
- if (((APIFlags & IMDISK_API_NO_BROADCAST_NOTIFY) == 0) &
- (MountPoint[0] >= L'A') & (MountPoint[0] <= L'Z'))
+ if (((APIFlags & IMDISK_API_NO_BROADCAST_NOTIFY) == 0) &&
+ (MountPoint[0] >= L'A') && (MountPoint[0] <= L'Z'))
{
if (hWnd != NULL)
- SetWindowText
- (hWnd,
- L"Notifying applications that device is being removed...");
+ {
+ SetWindowText(hWnd,
+ L"Notifying applications that device is being removed...");
+ }
ImDiskNotifyRemovePending(hWnd, MountPoint[0]);
}
@@ -2050,16 +2163,20 @@ LPCWSTR MountPoint)
NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if (device == INVALID_HANDLE_VALUE)
+ {
device = CreateFile(drive_letter_path,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ }
if (device == INVALID_HANDLE_VALUE)
+ {
device = CreateFile(drive_letter_path,
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ }
}
else
{
@@ -2070,32 +2187,41 @@ LPCWSTR MountPoint)
GENERIC_READ | GENERIC_WRITE);
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- GENERIC_READ);
+ GENERIC_READ);
+ }
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByMountPoint(MountPoint,
- FILE_READ_ATTRIBUTES);
+ FILE_READ_ATTRIBUTES);
+ }
}
if (device == INVALID_HANDLE_VALUE)
{
if (hWnd != NULL)
MsgBoxLastError(hWnd, L"Error opening device:");
+
return FALSE;
}
- if (!ImDiskCheckDriverVersion(device))
- if (GetLastError() != NO_ERROR)
+ if (!ImDiskCheckDriverVersion(device) &&
+ GetLastError() != NO_ERROR)
+ {
+ NtClose(device);
+
+ if (hWnd != NULL)
{
- NtClose(device);
- if (hWnd != NULL)
- ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"ImDisk Virtual Disk Driver",
+ ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP,
+ L"ImDisk Virtual Disk Driver",
L"Not an ImDisk Virtual Disk: '%1'", MountPoint);
-
- return FALSE;
}
+ return FALSE;
+ }
+
if (hWnd != NULL)
SetWindowText(hWnd, L"Flushing file buffers...");
@@ -2112,8 +2238,11 @@ LPCWSTR MountPoint)
0,
&dw,
NULL))
+ {
if (APIFlags & IMDISK_API_FORCE_DISMOUNT)
+ {
force_dismount = TRUE;
+ }
else if (hWnd == NULL)
{
NtClose(device);
@@ -2133,22 +2262,26 @@ LPCWSTR MountPoint)
return FALSE;
}
else
+ {
force_dismount = TRUE;
+ }
+ }
- if (hWnd != NULL)
- SetWindowText(hWnd, L"Dismounting filesystem...");
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"Dismounting filesystem...");
- DeviceIoControl(device,
- FSCTL_DISMOUNT_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &dw,
- NULL);
+ DeviceIoControl(device,
+ FSCTL_DISMOUNT_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &dw,
+ NULL);
- if (force_dismount)
- DeviceIoControl(device,
+ if (force_dismount)
+ {
+ DeviceIoControl(device,
FSCTL_LOCK_VOLUME,
NULL,
0,
@@ -2156,72 +2289,77 @@ LPCWSTR MountPoint)
0,
&dw,
NULL);
+ }
- // If interactive mode, check if image has been modified and if so ask user
- // if it should be saved first.
+ // If interactive mode, check if image has been modified and if so ask user
+ // if it should be saved first.
#ifndef CORE_BUILD
- if (hWnd != NULL)
- if (!ImDiskInteractiveCheckSave(hWnd, device))
- {
- NtClose(device);
- return FALSE;
- }
+ if (hWnd != NULL && !ImDiskInteractiveCheckSave(hWnd, device))
+ {
+ NtClose(device);
+ return FALSE;
+ }
#endif
- if (hWnd != NULL)
- SetWindowText(hWnd, L"Removing device...");
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"Removing device...");
- if (!DeviceIoControl(device,
- IOCTL_STORAGE_EJECT_MEDIA,
- NULL,
- 0,
- NULL,
- 0,
- &dw,
- NULL))
- if (force_dismount ? !ImDiskForceRemoveDevice(device, 0) : FALSE)
+ if (!DeviceIoControl(device,
+ IOCTL_STORAGE_EJECT_MEDIA,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &dw,
+ NULL))
+ {
+ if (force_dismount && !ImDiskForceRemoveDevice(device, 0))
+ {
+ if (hWnd != NULL)
{
- if (hWnd != NULL)
- MsgBoxLastError(hWnd, L"Error removing device:");
- NtClose(device);
- return FALSE;
+ MsgBoxLastError(hWnd, L"Error removing device:");
}
- DeviceIoControl(device,
- FSCTL_UNLOCK_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &dw,
- NULL);
+ NtClose(device);
+ return FALSE;
+ }
+ }
- NtClose(device);
+ DeviceIoControl(device,
+ FSCTL_UNLOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &dw,
+ NULL);
+
+ NtClose(device);
+
+ if (MountPoint != NULL)
+ {
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"Removing mount point...");
- if (MountPoint != NULL)
+ if (!ImDiskRemoveMountPoint(MountPoint))
{
if (hWnd != NULL)
- SetWindowText(hWnd, L"Removing mount point...");
-
- if (!ImDiskRemoveMountPoint(MountPoint))
{
- if (hWnd != NULL)
- {
- MsgBoxLastError(hWnd, L"Error removing drive letter:");
- }
+ MsgBoxLastError(hWnd, L"Error removing drive letter:");
}
}
+ }
- if (hWnd != NULL)
- SetWindowText(hWnd, L"OK.");
+ if (hWnd != NULL)
+ SetWindowText(hWnd, L"OK.");
- return TRUE;
+ return TRUE;
}
IMDISK_API BOOL
WINAPI
ImDiskForceRemoveDevice(HANDLE Device,
-DWORD DeviceNumber)
+ DWORD DeviceNumber)
{
UNICODE_STRING file_name;
HANDLE driver;
@@ -2249,8 +2387,10 @@ DWORD DeviceNumber)
}
RtlInitUnicodeString(&file_name, IMDISK_CTL_DEVICE_NAME);
+
driver = ImDiskOpenDeviceByName(&file_name,
GENERIC_READ | GENERIC_WRITE);
+
if (driver == NULL)
return FALSE;
@@ -2276,10 +2416,10 @@ DWORD DeviceNumber)
IMDISK_API BOOL
WINAPI
ImDiskChangeFlags(HWND hWnd,
-DWORD DeviceNumber,
-LPCWSTR MountPoint,
-DWORD FlagsToChange,
-DWORD Flags)
+ DWORD DeviceNumber,
+ LPCWSTR MountPoint,
+ DWORD FlagsToChange,
+ DWORD Flags)
{
HANDLE device;
DWORD dw;
@@ -2292,9 +2432,12 @@ DWORD Flags)
{
device = ImDiskOpenDeviceByNumber(DeviceNumber,
GENERIC_READ | GENERIC_WRITE);
+
if (device == INVALID_HANDLE_VALUE)
+ {
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
+ }
}
else if ((wcslen(MountPoint) == 2) ? MountPoint[1] == ':' :
(wcslen(MountPoint) == 3) ? wcscmp(MountPoint + 1, L":\\") == 0 :
@@ -2310,16 +2453,21 @@ DWORD Flags)
NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if (device == INVALID_HANDLE_VALUE)
+ {
device = CreateFile(drive_letter_path,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ }
}
else
{
if (hWnd != NULL)
+ {
ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"ImDisk Virtual Disk Driver",
- L"Unsupported mount point: '%1'", MountPoint);
+ L"Unsupported mount point: '%1'", MountPoint);
+ }
+
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
@@ -2335,9 +2483,12 @@ DWORD Flags)
if (GetLastError() != NO_ERROR)
{
NtClose(device);
+
if (hWnd != NULL)
+ {
ImDiskMsgBoxPrintF(hWnd, MB_ICONSTOP, L"ImDisk Virtual Disk Driver",
- L"Not an ImDisk Virtual Disk: '%1'", MountPoint);
+ L"Not an ImDisk Virtual Disk: '%1'", MountPoint);
+ }
return FALSE;
}
@@ -2358,6 +2509,7 @@ DWORD Flags)
0,
&dw,
NULL))
+ {
if (hWnd == NULL)
{
NtClose(device);
@@ -2376,6 +2528,7 @@ DWORD Flags)
return FALSE;
}
+ }
if (hWnd != NULL)
SetWindowText(hWnd, L"Dismounting filesystem...");
@@ -2388,6 +2541,7 @@ DWORD Flags)
0,
&dw,
NULL))
+ {
if (hWnd == NULL)
{
NtClose(device);
@@ -2404,6 +2558,7 @@ DWORD Flags)
return FALSE;
}
+ }
if (hWnd != NULL)
SetWindowText(hWnd, L"Setting device flags...");
@@ -2434,8 +2589,8 @@ DWORD Flags)
IMDISK_API BOOL
WINAPI
ImDiskExtendDevice(HWND hWnd,
-DWORD DeviceNumber,
-CONST PLARGE_INTEGER ExtendSize)
+ DWORD DeviceNumber,
+ CONST PLARGE_INTEGER ExtendSize)
{
HANDLE device;
DWORD dw;
@@ -2452,7 +2607,7 @@ CONST PLARGE_INTEGER ExtendSize)
if (device == INVALID_HANDLE_VALUE)
device = ImDiskOpenDeviceByNumber(DeviceNumber,
- GENERIC_READ);
+ GENERIC_READ);
if (device == INVALID_HANDLE_VALUE)
{
@@ -2493,10 +2648,11 @@ CONST PLARGE_INTEGER ExtendSize)
&dw, NULL))
{
if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
- L"An error occured when attempting to check the new total size of "
- L"the resized virtual disk:");
+ {
+ MsgBoxLastError(hWnd,
+ L"An error occurred when attempting to check the new total size of "
+ L"the resized virtual disk:");
+ }
NtClose(device);
return FALSE;
@@ -2511,10 +2667,11 @@ CONST PLARGE_INTEGER ExtendSize)
&dw, NULL))
{
if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
- L"An error occured when attempting to check the new total size of "
- L"the resized virtual disk:");
+ {
+ MsgBoxLastError(hWnd,
+ L"An error occurred when attempting to check the new total size of "
+ L"the resized virtual disk:");
+ }
NtClose(device);
return FALSE;
@@ -2531,12 +2688,15 @@ CONST PLARGE_INTEGER ExtendSize)
NULL,
0,
&dw, NULL))
+ {
if (hWnd != NULL)
- MsgBoxLastError
- (hWnd,
- L"The disk size was extended successfully, but it was not possible "
- L"to extend the current filesystem on it. You will have to reformat "
- L"the disk to use the full disk size.");
+ {
+ MsgBoxLastError(hWnd,
+ L"The disk size was extended successfully, but it was not possible "
+ L"to extend the current filesystem on it. You will have to reformat "
+ L"the disk to use the full disk size.");
+ }
+ }
NtClose(device);
return TRUE;
@@ -2545,9 +2705,9 @@ CONST PLARGE_INTEGER ExtendSize)
IMDISK_API BOOL
WINAPI
ImDiskSaveImageFile(IN HANDLE DeviceHandle,
-IN HANDLE FileHandle,
-IN DWORD BufferSize OPTIONAL,
-IN LPBOOL CancelFlag OPTIONAL)
+ IN HANDLE FileHandle,
+ IN DWORD BufferSize OPTIONAL,
+ IN LPBOOL CancelFlag OPTIONAL)
{
LPBYTE buffer;
IMDISK_SET_DEVICE_FLAGS device_flags = { 0 };
@@ -2648,7 +2808,7 @@ IN LPBOOL CancelFlag OPTIONAL)
IMDISK_API BOOL
WINAPI
ImDiskAdjustImageFileSize(IN HANDLE FileHandle,
-IN PLARGE_INTEGER FileSize)
+ IN PLARGE_INTEGER FileSize)
{
ULARGE_INTEGER existing_size = { 0 };
DWORD ptr;
@@ -2657,9 +2817,11 @@ IN PLARGE_INTEGER FileSize)
// original disk volume and possibly adjusts image file size if it does not
// exactly match the size of the original disk/partition.
existing_size.LowPart = GetFileSize(FileHandle, &existing_size.HighPart);
- if (existing_size.LowPart == INVALID_FILE_SIZE)
- if (GetLastError() != NO_ERROR)
- return FALSE;
+ if (existing_size.LowPart == INVALID_FILE_SIZE &&
+ GetLastError() != NO_ERROR)
+ {
+ return FALSE;
+ }
if (existing_size.QuadPart < (ULONGLONG)FileSize->QuadPart)
{
@@ -2671,9 +2833,12 @@ IN PLARGE_INTEGER FileSize)
FileSize->LowPart,
(LPLONG)&FileSize->HighPart,
FILE_BEGIN);
- if (ptr == INVALID_SET_FILE_POINTER)
- if (GetLastError() != NO_ERROR)
- return FALSE;
+
+ if (ptr == INVALID_SET_FILE_POINTER &&
+ GetLastError() != NO_ERROR)
+ {
+ return FALSE;
+ }
return SetEndOfFile(FileHandle);
}
@@ -2681,7 +2846,7 @@ IN PLARGE_INTEGER FileSize)
IMDISK_API BOOL
WINAPI
ImDiskGetVolumeSize(IN HANDLE Handle,
-IN OUT PLONGLONG Size)
+ IN OUT PLONGLONG Size)
{
PARTITION_INFORMATION partition_info = { 0 };
DISK_GEOMETRY disk_geometry = { 0 };
@@ -2732,8 +2897,8 @@ IN OUT PLONGLONG Size)
IMDISK_API BOOL
WINAPI
ImDiskGetFormattedGeometry(IN LPCWSTR ImageFile,
-IN PLARGE_INTEGER Offset OPTIONAL,
-IN OUT PDISK_GEOMETRY DiskGeometry)
+ IN PLARGE_INTEGER Offset OPTIONAL,
+ IN OUT PDISK_GEOMETRY DiskGeometry)
{
HANDLE hImageFile;
BOOL bResult;
@@ -2761,9 +2926,9 @@ IN OUT PDISK_GEOMETRY DiskGeometry)
IMDISK_API BOOL
WINAPI
ImDiskGetFormattedGeometryIndirect(IN HANDLE Handle,
-IN ImDiskReadFileProc ReadFileProc,
-IN PLARGE_INTEGER Offset OPTIONAL,
-IN OUT PDISK_GEOMETRY DiskGeometry)
+ IN ImDiskReadFileProc ReadFileProc,
+ IN PLARGE_INTEGER Offset OPTIONAL,
+ IN OUT PDISK_GEOMETRY DiskGeometry)
{
FAT_VBR fat_vbr;
LARGE_INTEGER offset = { 0 };
@@ -2787,10 +2952,10 @@ IN OUT PDISK_GEOMETRY DiskGeometry)
IMDISK_API BOOL
WINAPI
ImDiskBuildMBR(IN PDISK_GEOMETRY DiskGeometry OPTIONAL,
-IN PPARTITION_INFORMATION PartitionInformation OPTIONAL,
-IN BYTE NumberOfPartitions OPTIONAL,
-IN OUT LPBYTE MBR,
-IN DWORD_PTR MBRSize)
+ IN PPARTITION_INFORMATION PartitionInformation OPTIONAL,
+ IN BYTE NumberOfPartitions OPTIONAL,
+ IN OUT LPBYTE MBR,
+ IN DWORD_PTR MBRSize)
{
BYTE i;
@@ -2858,7 +3023,7 @@ IN DWORD_PTR MBRSize)
IMDISK_API DWORD
WINAPI
ImDiskConvertCHSToLBA(IN PDISK_GEOMETRY DiskGeometry,
-IN LPBYTE CHS)
+ IN LPBYTE CHS)
{
DWORD cylinder = (((DWORD)CHS[1] & 0xC0) << 2) | CHS[2];
DWORD heads = CHS[0];
@@ -2866,13 +3031,13 @@ IN LPBYTE CHS)
return
((cylinder * DiskGeometry->TracksPerCylinder + heads) *
- DiskGeometry->SectorsPerTrack) + sector - 1;
+ DiskGeometry->SectorsPerTrack) + sector - 1;
}
IMDISK_API DWORD
WINAPI
ImDiskConvertLBAToCHS(IN PDISK_GEOMETRY DiskGeometry,
-IN DWORD LBA)
+ IN DWORD LBA)
{
/*
cylinder = LBA / (heads_per_cylinder * sectors_per_track)
@@ -2897,8 +3062,8 @@ IN DWORD LBA)
temp %
DiskGeometry->SectorsPerTrack + 1;
- if ((cylinder >= 1024) |
- (head >= 256) |
+ if ((cylinder >= 1024) ||
+ (head >= 256) ||
(sector >= 64))
{
cylinder = 1023;
@@ -2915,12 +3080,16 @@ IN DWORD LBA)
IMDISK_API VOID
WINAPI
-ImDiskNativePathToWin32(IN OUT LPWSTR *Path)
+ImDiskNativePathToWin32(IN OUT LPWSTR* Path)
{
if ((Path == NULL) || (Path[0] == 0))
+ {
return;
+ }
else if (wcsncmp(*Path, L"\\??\\", 4) == 0)
+ {
(*Path)[1] = L'\\';
+ }
else if (wcsncmp(*Path, L"\\DosDevices\\", 12) == 0)
{
(*Path) += 8;
@@ -2929,10 +3098,14 @@ ImDiskNativePathToWin32(IN OUT LPWSTR *Path)
(*Path)[3] = L'?';
}
else
+ {
return;
+ }
- if ((*Path)[4] != 0 ? (*Path)[5] == L':' : FALSE)
+ if ((*Path)[4] != 0 && (*Path)[5] == L':')
+ {
(*Path) += 4;
+ }
else if (wcsncmp(*Path, L"\\\\?\\UNC\\", 8) == 0)
{
(*Path) += 6;
@@ -2947,16 +3120,23 @@ ImDiskOpenRefreshEvent(BOOL InheritHandle)
SECURITY_ATTRIBUTES sec_attrs = { 0 };
PSECURITY_DESCRIPTOR sec_descr = NULL;
HANDLE hEvent = NULL;
- WCHAR *objname;
+ WCHAR* objname;
HANDLE h = CreateFile(L"\\\\?\\Global", 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
if ((h == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
objname = IMDISK_REFRESH_EVENT_NAME;
+ }
else
+ {
objname = L"Global\\" IMDISK_REFRESH_EVENT_NAME;
+ }
if (h != INVALID_HANDLE_VALUE)
+ {
CloseHandle(h);
+ }
// Initialize a security descriptor.
sec_descr = (PSECURITY_DESCRIPTOR)
@@ -3028,21 +3208,29 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
&value_size);
if (err_code == ERROR_SUCCESS)
+ {
if (CreateData->DeviceNumber == IMDISK_AUTO_DEVICE_NUMBER)
{
CreateData->DeviceNumber = load_devices;
++load_devices;
}
else
+ {
load_devices = max(load_devices, CreateData->DeviceNumber + 1);
+ }
+ }
else
+ {
if (CreateData->DeviceNumber == IMDISK_AUTO_DEVICE_NUMBER)
{
CreateData->DeviceNumber = 0;
load_devices = 1;
}
else
+ {
load_devices = CreateData->DeviceNumber + 1;
+ }
+ }
err_code = RegSetValueEx(hkey,
IMDISK_CFG_LOAD_DEVICES_VALUE,
@@ -3060,6 +3248,7 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
value_name = ImDiskAllocPrintF(IMDISK_CFG_IMAGE_FILE_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3070,9 +3259,9 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
{
LPWSTR value_data =
ImDiskAllocPrintF(L"%1!.*ws!",
- (int)(CreateData->FileNameLength /
- sizeof(*CreateData->FileName)),
- CreateData->FileName);
+ (int)(CreateData->FileNameLength /
+ sizeof(*CreateData->FileName)),
+ CreateData->FileName);
if (value_data == NULL)
{
@@ -3097,12 +3286,15 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
value_name = ImDiskAllocPrintF(IMDISK_CFG_SIZE_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3126,12 +3318,15 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
value_name = ImDiskAllocPrintF(IMDISK_CFG_FLAGS_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3155,12 +3350,15 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
value_name = ImDiskAllocPrintF(IMDISK_CFG_DRIVE_LETTER_PREFIX L"%1!u!",
CreateData->DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3187,7 +3385,9 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
@@ -3216,7 +3416,9 @@ ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData)
}
}
else
+ {
RegDeleteValue(hkey, value_name);
+ }
LocalFree(value_name);
@@ -3283,6 +3485,7 @@ ImDiskRemoveRegistrySettings(DWORD DeviceNumber)
value_name = ImDiskAllocPrintF(IMDISK_CFG_IMAGE_FILE_PREFIX L"%1!u!",
DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3295,6 +3498,7 @@ ImDiskRemoveRegistrySettings(DWORD DeviceNumber)
value_name = ImDiskAllocPrintF(IMDISK_CFG_SIZE_PREFIX L"%1!u!",
DeviceNumber);
+
if (value_name == NULL)
{
RegCloseKey(hkey);
@@ -3384,3 +3588,40 @@ ImDiskGetRegistryAutoLoadDevices(LPDWORD LoadDevicesValue)
return TRUE;
}
+
+BOOL
+WINAPI
+ImDiskIsProcessElevated()
+{
+ HANDLE hToken;
+ TOKEN_ELEVATION elevation;
+ DWORD dwSize;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ {
+ return FALSE;
+ }
+
+ if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize))
+ {
+ DWORD dwerr = GetLastError();
+ CloseHandle(hToken);
+ SetLastError(dwerr);
+
+ switch (dwerr)
+ {
+ case ERROR_INVALID_FUNCTION:
+ case ERROR_INVALID_PARAMETER:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ CloseHandle(hToken);
+
+ SetLastError(NO_ERROR);
+
+ return elevation.TokenIsElevated;
+}
diff --git a/cplcore/drvio.h b/cplcore/drvio.h
index a17263a..6e0d8c2 100644
--- a/cplcore/drvio.h
+++ b/cplcore/drvio.h
@@ -2,17 +2,31 @@
extern "C" {
#endif
- INT_PTR
- CALLBACK
- StatusDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ INT_PTR
+ CALLBACK
+ StatusDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- INT_PTR
- CALLBACK
- NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ INT_PTR
+ CALLBACK
+ NewDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL
- WINAPI
- ImDiskInteractiveCheckSave(HWND hWnd, HANDLE device);
+ BOOL
+ WINAPI
+ ImDiskInteractiveCheckSave(HWND hWnd, HANDLE device);
+
+ LONG
+ WINAPI
+ ImDiskShowCPlAppletElevated(HWND hWnd);
+
+ VOID
+ WINAPI
+ ImDiskRelaunchElevated(HWND hWnd, LPCSTR DllFunction,
+ LPCSTR CommandLine, int nCmdShow);
+
+ VOID
+ WINAPI
+ ImDiskRelaunchElevatedW(HWND hWnd, LPCWSTR DllFunction,
+ LPCWSTR CommandLine, int nCmdShow);
/**
This function is a quick perror-style way of displaying an error message
@@ -25,7 +39,7 @@ extern "C" {
VOID
WINAPI
MsgBoxLastError(IN HWND hWndParent OPTIONAL,
- IN LPCWSTR Prefix);
+ IN LPCWSTR Prefix);
extern
ULONGLONG
diff --git a/cplcore/i386/imdisk.exp b/cplcore/i386/imdisk.exp
index 20e5e28..ba32140 100644
Binary files a/cplcore/i386/imdisk.exp and b/cplcore/i386/imdisk.exp differ
diff --git a/cplcore/i386/imdisk.lib b/cplcore/i386/imdisk.lib
index c205afc..b895af8 100644
Binary files a/cplcore/i386/imdisk.lib and b/cplcore/i386/imdisk.lib differ
diff --git a/cplcore/ia64/imdisk.exp b/cplcore/ia64/imdisk.exp
index 880d9da..6387f6b 100644
Binary files a/cplcore/ia64/imdisk.exp and b/cplcore/ia64/imdisk.exp differ
diff --git a/cplcore/ia64/imdisk.lib b/cplcore/ia64/imdisk.lib
index 2332046..65d3c00 100644
Binary files a/cplcore/ia64/imdisk.lib and b/cplcore/ia64/imdisk.lib differ
diff --git a/cplcore/imdisk.rc b/cplcore/imdisk.rc
index 9b3dfe8..5e1c848 100644
--- a/cplcore/imdisk.rc
+++ b/cplcore/imdisk.rc
@@ -37,7 +37,7 @@ FILESUBTYPE 0
VALUE "FileDescription", "Control Panel Applet for the ImDisk Virtual Disk Driver\0"
VALUE "FileVersion", IMDISK_RC_VERSION_STR ".59\0"
VALUE "InternalName", "imdisk\0"
- VALUE "LegalCopyright", "Copyright © 2004-2018 Olof Lagerkvist.\0"
+ VALUE "LegalCopyright", "Copyright © 2004-2021 Olof Lagerkvist.\0"
VALUE "OriginalFilename", "imdisk.cpl\0"
VALUE "ProductName", "imdisk\0"
VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".59\0"
diff --git a/cplcore/imdisk.vcxproj b/cplcore/imdisk.vcxproj
deleted file mode 100644
index 4363a07..0000000
--- a/cplcore/imdisk.vcxproj
+++ /dev/null
@@ -1,201 +0,0 @@
-
-
-
-
- Win8.1 Debug
- Win32
-
-
- Win8 Debug
- Win32
-
-
- Win7 Debug
- Win32
-
-
- Win8.1 Release
- Win32
-
-
- Win8 Release
- Win32
-
-
- Win7 Release
- Win32
-
-
- Win8.1 Debug
- x64
-
-
- Win8 Debug
- x64
-
-
- Win7 Debug
- x64
-
-
- Win8.1 Release
- x64
-
-
- Win8 Release
- x64
-
-
- Win7 Release
- x64
-
-
-
- WindowsApplicationForDrivers8.1
- DynamicLibrary
-
- imdisk
- Win8.1 Debug
- Win32
-
-
-
- 1.0
- $(Configuration.Replace(' ',''))
- $(BUILD_ALT_DIR)\$(Platform)\
- $(BUILD_ALT_DIR)\x86\
- $(IntDir)
-
-
-
-
-
- {99A7A6E5-AC73-4FB9-BA97-9C206F06A3C7}
- $(MSBuildProjectName)
-
-
- WindowsV6.3
- True
-
-
- Win8
- True
-
-
- Win7
- True
-
-
- WindowsV6.3
- False
-
-
- Win8
- False
-
-
- Win7
- False
-
-
- WindowsV6.3
- True
-
-
- Win8
- True
-
-
- Win7
- True
-
-
- WindowsV6.3
- False
-
-
- Win8
- False
-
-
- Win7
- False
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(KIT_SHARED_INC_PATH)
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/cplcore/mbr.c b/cplcore/mbr.c
new file mode 100644
index 0000000..7428909
--- /dev/null
+++ b/cplcore/mbr.c
@@ -0,0 +1,89 @@
+#include "mbr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef INCLUDE_GPL_ORIGIN
+
+ const char default_mbr[] =
+ {
+ 0xFA, 0xFC, 0x31, 0xC0, 0x8E, 0xD0, 0x8E, 0xD8, 0xBD, 0x00, 0x7C, 0x8D, 0x66, 0xE0, 0xFB, 0xB8,
+ 0xE0, 0x1F, 0x8E, 0xC0, 0x89, 0xEE, 0x89, 0xEF, 0xB9, 0x00, 0x01, 0xF3, 0xA5, 0xEA, 0x22, 0x7C,
+ 0xE0, 0x1F, 0x8E, 0xD8, 0x8E, 0xD0, 0x31, 0xC0, 0x8E, 0xC0, 0x8D, 0xBE, 0xBE, 0x01, 0xF6, 0x05,
+ 0x80, 0x75, 0x71, 0x81, 0xC7, 0x10, 0x00, 0x81, 0xFF, 0xFE, 0x7D, 0x72, 0xF1, 0xE8, 0xC7, 0x00,
+ 0x6E, 0x6F, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
+ 0x69, 0x6F, 0x6E, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x00, 0xE9, 0xFD, 0xFF, 0xE8, 0xA7, 0x00,
+ 0x72, 0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20, 0x77, 0x68, 0x69, 0x6C, 0x65,
+ 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x00, 0xE9,
+ 0xD8, 0xFF, 0xE8, 0x82, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73,
+ 0x69, 0x67, 0x6E, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x21, 0x3D, 0x20, 0x35, 0x35, 0x41, 0x41,
+ 0x00, 0xE9, 0xB6, 0xFF, 0xE8, 0x10, 0x00, 0x72, 0xB4, 0x26, 0x81, 0x3E, 0xFE, 0x7D, 0x55, 0xAA,
+ 0x75, 0xD0, 0xEA, 0x00, 0x7C, 0x00, 0x00, 0xBB, 0xAA, 0x55, 0xB4, 0x41, 0xCD, 0x13, 0x72, 0x32,
+ 0x81, 0xFB, 0x55, 0xAA, 0x75, 0x2C, 0xF6, 0xC1, 0x01, 0x74, 0x27, 0xEB, 0x10, 0x10, 0x00, 0x04,
+ 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x45, 0x08,
+ 0xA3, 0xD5, 0x7C, 0x8B, 0x45, 0x0A, 0xA3, 0xD7, 0x7C, 0xB8, 0x00, 0x42, 0xBE, 0xCD, 0x7C, 0xCD,
+ 0x13, 0xC3, 0xB8, 0x04, 0x02, 0xBB, 0x00, 0x7C, 0x8B, 0x4D, 0x02, 0x8A, 0x75, 0x01, 0xCD, 0x13,
+ 0xC3, 0x31, 0xDB, 0xB4, 0x0E, 0xCD, 0x10, 0x5E, 0xAC, 0x56, 0x3C, 0x00, 0x75, 0xF3, 0xC3, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA,
+ };
+
+#else // INCLUDE_GPL_ORIGIN
+
+ const char default_mbr[] =
+ {
+ 0xF4, 0xEB, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA
+ };
+
+#endif // INCLUDE_GPL_ORIGIN
+
+const unsigned int default_mbr_size = sizeof(default_mbr);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cplcore/sources b/cplcore/sources
index bc6eed1..343bcca 100644
--- a/cplcore/sources
+++ b/cplcore/sources
@@ -2,7 +2,7 @@ TARGETNAME=imdisk
TARGETEXT=cpl
TARGETPATH=.
TARGETTYPE=DYNLINK
-C_DEFINES = $(C_DEFINES) /DUNICODE /D_UNICODE /DNT4_COMPATIBLE /DIMDISK_CPL_EXPORTS /DCORE_BUILD
+C_DEFINES = $(C_DEFINES) /DUNICODE /D_UNICODE /DNT4_COMPATIBLE /DIMDISK_CPL_EXPORTS /DCORE_BUILD /DINCLUDE_GPL_ORIGIN
UMTYPE=windows
USE_MSVCRT=1
MSC_OPTIMIZATION=/Ox /GF
diff --git a/cplcore/sources.props b/cplcore/sources.props
index 998d730..986185a 100644
--- a/cplcore/sources.props
+++ b/cplcore/sources.props
@@ -5,7 +5,7 @@
cpl
.
DYNLINK
- $(C_DEFINES) /DUNICODE /D_UNICODE
+ $(C_DEFINES) /DUNICODE /D_UNICODE /DINCLUDE_GPL_ORIGIN
windows
1
/Ox /GF
diff --git a/cplcore/wconmsg.cpp b/cplcore/wconmsg.cpp
index c80714b..0a648d7 100644
--- a/cplcore/wconmsg.cpp
+++ b/cplcore/wconmsg.cpp
@@ -1,7 +1,7 @@
/*
No-GUI support for the ImDisk Virtual Disk Driver for Windows NT/2000/XP.
-Copyright (C) 2007-2018 Olof Lagerkvist.
+Copyright (C) 2007-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/devio/Makefile b/devio/Makefile
index 8e80909..79dd867 100644
--- a/devio/Makefile
+++ b/devio/Makefile
@@ -6,11 +6,13 @@ UNAME_M?=$(shell uname -m)
UNAME=$(UNAME_S)_$(UNAME_M)
+DIST=../dist
+
default: devio.$(UNAME)
static: devio.static.$(UNAME)
-publish: /usr/utils/devio.gz /usr/utils/devio.xz
+publish: $(DIST)/devio_$(UNAME).gz $(DIST)/devio_$(UNAME).xz $(DIST)/devio_$(UNAME).bz2 $(DIST)/devio_static_$(UNAME).gz $(DIST)/devio_static_$(UNAME).xz $(DIST)/devio_static_$(UNAME).bz2
install: /usr/local/bin/devio
@@ -22,11 +24,23 @@ devio.$(UNAME): devio.c ../inc/*.h safeio.c safeio.h devio_types.h Makefile
devio.static.$(UNAME): devio.c ../inc/*.h safeio.c safeio.h devio_types.h Makefile
cc $(CC_OPT) -static -o devio.static.$(UNAME) devio.c safeio.c
-/usr/utils/devio.gz: devio.static.$(UNAME)
- gzip -9 < devio.static.$(UNAME) > /usr/utils/devio_$(UNAME).gz
+$(DIST)/devio_$(UNAME).gz: devio.static.$(UNAME)
+ gzip -9 < devio.$(UNAME) > $(DIST)/devio_$(UNAME).gz
+
+$(DIST)/devio_$(UNAME).xz: devio.static.$(UNAME)
+ xz < devio.$(UNAME) > $(DIST)/devio_$(UNAME).xz
+
+$(DIST)/devio_$(UNAME).bz2: devio.static.$(UNAME)
+ bzip2 < devio.$(UNAME) > $(DIST)/devio_$(UNAME).bz2
+
+$(DIST)/devio_static_$(UNAME).gz: devio.static.$(UNAME)
+ gzip -9 < devio.static.$(UNAME) > $(DIST)/devio_static_$(UNAME).gz
+
+$(DIST)/devio_static_$(UNAME).xz: devio.static.$(UNAME)
+ xz < devio.static.$(UNAME) > $(DIST)/devio_static_$(UNAME).xz
-/usr/utils/devio.xz: devio.static.$(UNAME)
- xz < devio.static.$(UNAME) > /usr/utils/devio_$(UNAME).xz
+$(DIST)/devio_static_$(UNAME).bz2: devio.static.$(UNAME)
+ bzip2 < devio.static.$(UNAME) > $(DIST)/devio_static_$(UNAME).bz2
/usr/local/bin/devio: devio.$(UNAME)
install devio.$(UNAME) /usr/local/bin/devio
diff --git a/devio/Makefile.win64d b/devio/Makefile.win64d
new file mode 100644
index 0000000..2a7d0da
--- /dev/null
+++ b/devio/Makefile.win64d
@@ -0,0 +1,10 @@
+all: Debug\x64\devio.exe
+
+Debug\x64\devio.obj: devio.c ..\inc\*.h safeio.h devio.h devio_types.h Makefile.win64
+ cl /c /DDEBUG /D_DEBUG /WX /W4 /wd4201 /wd4204 /wd4996 /Od /GR- /MD /FoDebug\x64\devio.obj /nologo devio.c
+
+Debug\x64\safeio_win32.obj: safeio_win32.cpp ..\inc\*.h safeio.h devio.h devio_types.h Makefile.win64
+ cl /c /DDEBUG /D_DEBUG /WX /W4 /wd4201 /wd4204 /wd4996 /Od /GR- /MD /FoDebug\x64\safeio_win32.obj /nologo safeio_win32.cpp
+
+Debug\x64\devio.exe: Debug\x64\devio.obj Debug\x64\safeio_win32.obj Makefile.win64
+ link /opt:nowin98,ref,icf=10 /largeaddressaware /defaultlib:bufferoverflowU.lib /release /debug /nologo /out:Debug\x64\devio.exe Debug\x64\devio.obj Debug\x64\safeio_win32.obj
diff --git a/devio/Makefile.winarm b/devio/Makefile.winarm
new file mode 100644
index 0000000..953d838
--- /dev/null
+++ b/devio/Makefile.winarm
@@ -0,0 +1,18 @@
+all: Release\arm\devio.exe
+
+publish: P:\UtilsARM\devio.exe Z:\ltr-website\ltr-data.se\files\winRelease\arm\devio.exe
+
+P:\UtilsARM\devio.exe: Release\arm\devio.exe
+ copy /y Release\arm\devio.exe P:\UtilsARM\\
+
+Z:\ltr-website\ltr-data.se\files\winarm\devio.exe: Release\arm\devio.exe
+ copy /y Release\arm\devio.exe Z:\ltr-website\ltr-data.se\files\winarm\\
+
+Release\arm\devio.obj: devio.c ..\inc\*.h safeio.h devio.h devio_types.h Makefile.winarm
+ cl /c /WX /W4 /wd4201 /wd4204 /wd4996 /Ox /GR- /MD /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE /D_MSC_PLATFORM_TOOLSET=120 /FoRelease\arm\devio.obj /nologo devio.c
+
+Release\arm\safeio_win32.obj: safeio_win32.cpp ..\inc\*.h safeio.h devio.h devio_types.h Makefile.winarm
+ cl /c /WX /W4 /wd4201 /wd4204 /wd4996 /Ox /GR- /MD /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE /D_MSC_PLATFORM_TOOLSET=120 /FoRelease\arm\safeio_win32.obj /nologo safeio_win32.cpp
+
+Release\arm\devio.exe: Release\arm\devio.obj Release\arm\safeio_win32.obj Makefile.winarm
+ link /opt:ref,icf=10 /largeaddressaware /release /debug /nologo /out:Release\arm\devio.exe Release\arm\devio.obj Release\arm\safeio_win32.obj
diff --git a/devio/Makefile.winarm64 b/devio/Makefile.winarm64
new file mode 100644
index 0000000..cabe4f7
--- /dev/null
+++ b/devio/Makefile.winarm64
@@ -0,0 +1,18 @@
+all: Release\arm64\devio.exe
+
+publish: P:\UtilsARM\devio.exe Z:\ltr-website\ltr-data.se\files\winRelease\arm64\devio.exe
+
+P:\UtilsARM\devio.exe: Release\arm64\devio.exe
+ copy /y Release\arm64\devio.exe P:\UtilsARM\\
+
+Z:\ltr-website\ltr-data.se\files\winarm64\devio.exe: Release\arm64\devio.exe
+ copy /y Release\arm64\devio.exe Z:\ltr-website\ltr-data.se\files\winarm64\\
+
+Release\arm64\devio.obj: devio.c ..\inc\*.h safeio.h devio.h devio_types.h Makefile.winarm
+ cl /c /WX /W4 /wd4201 /wd4204 /wd4996 /Ox /GR- /MD /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE /D_MSC_PLATFORM_TOOLSET=140 /FoRelease\arm64\devio.obj /nologo devio.c
+
+Release\arm64\safeio_win32.obj: safeio_win32.cpp ..\inc\*.h safeio.h devio.h devio_types.h Makefile.winarm
+ cl /c /WX /W4 /wd4201 /wd4204 /wd4996 /Ox /GR- /MD /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE /D_MSC_PLATFORM_TOOLSET=140 /FoRelease\arm64\safeio_win32.obj /nologo safeio_win32.cpp
+
+Release\arm64\devio.exe: Release\arm64\devio.obj Release\arm64\safeio_win32.obj Makefile.winarm
+ link /opt:ref,icf=10 /largeaddressaware /release /debug /nologo /out:Release\arm64\devio.exe Release\arm64\devio.obj Release\arm64\safeio_win32.obj
diff --git a/devio/devio.c b/devio/devio.c
index 76fe5ac..afbdab3 100644
--- a/devio/devio.c
+++ b/devio/devio.c
@@ -1,7 +1,7 @@
/*
Server end for ImDisk Virtual Disk Driver proxy operation.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -43,6 +43,7 @@ OTHER DEALINGS IN THE SOFTWARE.
#include
#include
#include
+#include
#ifdef _WIN32
@@ -91,15 +92,34 @@ syslog(FILE *Stream, LPCSTR Message, ...)
{
va_list param_list;
LPSTR MsgBuf = NULL;
+ LPSTR msgptr = NULL;
+ LPSTR alloc_msg = NULL;
va_start(param_list, Message);
- if (strstr(Message, "%m") != NULL)
+ msgptr = strstr(Message, "%m");
+
+ if (msgptr != NULL)
{
+ size_t msgpos = msgptr - Message;
+
DWORD winerrno = GetLastError();
if (winerrno == NO_ERROR)
+ {
winerrno = 10000 + errno;
+ }
+
+ alloc_msg = _strdup(Message);
+
+ if (alloc_msg == NULL)
+ {
+ return;
+ }
+
+ msgptr = alloc_msg + msgpos;
+
+ *msgptr = 0;
if (FormatMessage(FORMAT_MESSAGE_MAX_WIDTH_MASK |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -113,6 +133,8 @@ syslog(FILE *Stream, LPCSTR Message, ...)
{
MsgBuf = NULL;
}
+
+ Message = alloc_msg;
}
if (MsgBuf != NULL)
@@ -123,7 +145,14 @@ syslog(FILE *Stream, LPCSTR Message, ...)
LocalFree(MsgBuf);
}
else
+ {
vfprintf(Stream, Message, param_list);
+ }
+
+ if (alloc_msg != NULL)
+ {
+ free(alloc_msg);
+ }
fflush(Stream);
return;
@@ -142,14 +171,15 @@ HANDLE shm_server_mutex = NULL;
HANDLE shm_request_event = NULL;
HANDLE shm_response_event = NULL;
+OVERLAPPED drv_memory_io;
+OVERLAPPED drv_request_io;
+
#else // Unix
#include
#include
#include
#include
-#include
-#include
#include
#include
#include
@@ -169,26 +199,16 @@ HANDLE shm_response_event = NULL;
#define O_FSYNC 0
#endif
-#define DEF_BUFFER_SIZE (64 << 20)
+#define DEF_BUFFER_SIZE ((int)((sizeof(void*) << 3) << 20))
#define DEF_REQUIRED_ALIGNMENT 1
-#ifdef DEBUG
+#if defined(DEBUG) || defined(_DEBUG) || defined(DBG) || defined(SYSLOG)
#define dbglog(x) syslog x
#else
#define dbglog(x)
#endif
-//typedef union _LONGLONG_SWAP
-//{
-// int64_t v64;
-// struct
-// {
-// int32_t v1;
-// int32_t v2;
-// } v32;
-//} longlongswap;
-
int64_t GetBigEndian64(int8_t *storage)
{
int i;
@@ -224,6 +244,7 @@ safeio_size_t buffer_size = DEF_BUFFER_SIZE;
off_t_64 image_offset = 0;
IMDPROXY_INFO_RESP devio_info = { 0 };
char dll_mode = 0;
+char drv_mode = 0;
char vhd_mode = 0;
char auto_vhd_detect = 1;
@@ -316,6 +337,86 @@ physical_close(int fd)
#ifdef _WIN32
+int alloc_drv_buffer()
+{
+ HANDLE hFileMap = NULL;
+ safeio_size_t detected_buffer_size;
+ MEMORY_BASIC_INFORMATION memory_info;
+ ULARGE_INTEGER map_size = { 0 };
+
+ printf("Allocating new buffer: " SIZ_FMT " bytes.\n", buffer_size);
+
+ map_size.QuadPart = (ULONGLONG)buffer_size + IMDPROXY_HEADER_SIZE;
+
+ hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE | SEC_COMMIT,
+ map_size.HighPart,
+ map_size.LowPart,
+ NULL);
+
+ if (hFileMap == NULL)
+ {
+ syslog(LOG_ERR, "CreateFileMapping() failed: %m\n");
+ return 2;
+ }
+
+ shm_view = (char*)MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
+
+ if (shm_view == NULL)
+ {
+ syslog(LOG_ERR, "MapViewOfFile() failed: %m\n");
+ return 2;
+ }
+
+ CloseHandle(hFileMap);
+
+ buf = shm_view + IMDPROXY_HEADER_SIZE;
+
+ if (!VirtualQuery(shm_view, &memory_info, sizeof(memory_info)))
+ {
+ syslog(LOG_ERR, "VirtualQuery() failed: %m\n");
+ return 2;
+ }
+
+ memset(shm_view, 0, memory_info.RegionSize);
+
+ detected_buffer_size = (safeio_size_t)
+ (memory_info.RegionSize - IMDPROXY_HEADER_SIZE);
+
+ if (buffer_size != detected_buffer_size)
+ {
+ buffer_size = detected_buffer_size;
+ if (buf2 != NULL)
+ {
+ free(buf2);
+ buf2 = (char*)malloc(buffer_size);
+ if (buf2 == NULL)
+ {
+ syslog(LOG_ERR, "malloc() failed: %m\n");
+ return 2;
+ }
+ }
+ }
+
+ ResetEvent(drv_memory_io.hEvent);
+
+ if (!DeviceIoControl((HANDLE)sd, IOCTL_DEVIODRV_LOCK_MEMORY, &shm_view, sizeof(void*), shm_view, buffer_size + IMDPROXY_HEADER_SIZE, NULL, &drv_memory_io))
+ {
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ dbglog((LOG_ERR, "Memory successfully locked.\n"));
+ }
+ else
+ {
+ syslog(LOG_ERR, "Lock memory request failed: %m\n");
+ return 3;
+ }
+ }
+
+ return 0;
+}
+
int
shm_read(void *io_ptr, safeio_size_t size)
{
@@ -326,7 +427,10 @@ shm_read(void *io_ptr, safeio_size_t size)
return 0;
if (shm_readptr == NULL)
- shm_readptr = shm_view;
+ if (drv_mode)
+ shm_readptr = shm_view + sizeof(IMDPROXY_DEVIODRV_BUFFER_HEADER);
+ else
+ shm_readptr = shm_view;
if ((long long)size > (long long)(buf - shm_readptr))
return 0;
@@ -347,7 +451,10 @@ shm_write(const void *io_ptr, safeio_size_t size)
return 0;
if (shm_writeptr == NULL)
- shm_writeptr = shm_view;
+ if (drv_mode)
+ shm_writeptr = shm_view + sizeof(IMDPROXY_DEVIODRV_BUFFER_HEADER);
+ else
+ shm_writeptr = shm_view;
if ((long long)size > (long long)(buf - shm_writeptr))
return 0;
@@ -376,6 +483,78 @@ shm_flush()
return 1;
}
+int
+drv_flush()
+{
+ DWORD dw;
+
+ shm_readptr = NULL;
+ shm_writeptr = NULL;
+
+ dbglog((LOG_ERR, "Calling DeviceIoControl for exchanging requests.\n"));
+
+ ResetEvent(drv_request_io.hEvent);
+
+ while (!DeviceIoControl((HANDLE)sd, IOCTL_DEVIODRV_EXCHANGE_IO, &shm_view, sizeof(void*), NULL, 0, &dw, &drv_request_io))
+ {
+ DWORD err = GetLastError();
+
+ if (err == ERROR_IO_PENDING)
+ {
+ dbglog((LOG_ERR, "Waiting for request to complete.\n"));
+
+ if (GetOverlappedResult((HANDLE)sd, &drv_request_io, &dw, TRUE))
+ {
+ dbglog((LOG_ERR, "Request complete.\n"));
+
+ break;
+ }
+
+ err = GetLastError();
+ }
+
+ dbglog((LOG_ERR, "Request failed: %i %m", err));
+
+ if (err == ERROR_INSUFFICIENT_BUFFER)
+ {
+ // need larger buffer (for write request, detected in driver)
+ dbglog((LOG_ERR, "Larger buffer needed.\n"));
+
+ if (!GetOverlappedResult((HANDLE)sd, &drv_memory_io, &dw, TRUE) &&
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ syslog(LOG_ERR, "Error waiting for memory unlock: %i %m", GetLastError());
+ }
+
+ UnmapViewOfFile(shm_view);
+
+ shm_view = NULL;
+
+ buffer_size <<= 1;
+
+ if (alloc_drv_buffer() == 0)
+ {
+ continue;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else if (err == ERROR_DEV_NOT_EXIST)
+ {
+ return 1;
+ }
+ else
+ {
+ syslog(LOG_ERR, "DeviceIoControl() failed: %m\n", err);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
#else // Unix
int
@@ -396,13 +575,91 @@ shm_flush()
return 0;
}
+int
+drv_flush()
+{
+ return 0;
+}
+
+#endif
+
+void
+buf_realloc(ULONGLONG new_size)
+{
+ if (shm_mode)
+ return;
+
+ if (new_size > (((safeio_size_t)-1) >> 1))
+ {
+ new_size = (((safeio_size_t)-1) >> 1);
+ }
+
+ buffer_size = (safeio_size_t)new_size;
+
+ dbglog((LOG_ERR, "Read request " SLL_FMT " bytes, reallocating buffer.\n",
+ (off_t_64)buffer_size));
+
+#ifdef _WIN32
+ if (drv_mode)
+ {
+ DWORD dw;
+
+ char* existing_buf = buf;
+ char* existing_buf2 = buf2;
+ char* existing_shm_view = shm_view;
+ safeio_size_t existing_buffer_size = buffer_size;
+
+ if (!GetOverlappedResult((HANDLE)sd, &drv_memory_io, &dw, TRUE) &&
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ syslog(LOG_ERR, "Error waiting for memory unlock: %i %m", GetLastError());
+ }
+
+ if (alloc_drv_buffer() == 0)
+ {
+ memcpy(shm_view, existing_shm_view, IMDPROXY_HEADER_SIZE);
+ UnmapViewOfFile(existing_shm_view);
+ free(existing_buf2);
+ }
+ else
+ {
+ shm_view = existing_shm_view;
+ buf = existing_buf;
+ buf2 = existing_buf2;
+ buffer_size = existing_buffer_size;
+ }
+ }
+ else
#endif
+ {
+ char *new_buf = (char*)malloc(buffer_size);
+ char *new_buf2 = (char*)malloc(buffer_size);
+ if (new_buf == NULL || new_buf2 == NULL)
+ {
+ syslog(LOG_ERR, "Failed allocating new buffer: %m\n");
+
+ if (new_buf != NULL)
+ free(new_buf);
+ if (new_buf2 != NULL)
+ free(new_buf2);
+ }
+ else
+ {
+ free(buf);
+ buf = new_buf;
+ free(buf2);
+ buf2 = new_buf2;
+ }
+ }
+}
int
comm_flush()
{
if (shm_mode)
return shm_flush();
+ else if (drv_mode)
+ return drv_flush();
else
return 1;
}
@@ -410,7 +667,7 @@ comm_flush()
int
comm_read(void *io_ptr, safeio_size_t size)
{
- if (shm_mode)
+ if (shm_mode || drv_mode)
return shm_read(io_ptr, size);
else
return safe_read(sd, io_ptr, size);
@@ -419,7 +676,7 @@ comm_read(void *io_ptr, safeio_size_t size)
int
comm_write(const void *io_ptr, safeio_size_t size)
{
- if (shm_mode)
+ if (shm_mode || drv_mode)
return shm_write(io_ptr, size);
else
return safe_write(sd, io_ptr, size);
@@ -434,6 +691,7 @@ send_info()
if (!comm_flush())
{
syslog(LOG_ERR, "Error flushing comm data: %m\n");
+
return 0;
}
@@ -491,6 +749,7 @@ vhd_read(char *io_ptr, safeio_size_t size, off_t_64 offset)
(((off_t_64)block_offset) << sector_shift) + sector_size +
in_block_offset;
+ readdone = physical_read(io_ptr, (safeio_size_t)first_size, data_offset);
readdone = physical_read(io_ptr, (safeio_size_t)first_size, data_offset);
if (readdone == -1)
return (safeio_ssize_t)-1;
@@ -735,13 +994,18 @@ read_data()
return 0;
}
+ if (req_block.length > buffer_size) // we will need larger buffer to complete this request
+ {
+ buf_realloc(req_block.length);
+ }
+
size = (safeio_size_t)
(req_block.length < buffer_size ? req_block.length : buffer_size);
dbglog((LOG_ERR, "read request " ULL_FMT " bytes at " ULL_FMT " + "
ULL_FMT " = " ULL_FMT ".\n",
- req_block.length, req_block.offset, offset,
- req_block.offset + offset));
+ req_block.length, req_block.offset, image_offset,
+ req_block.offset + image_offset));
memset(buf, 0, size);
@@ -804,8 +1068,8 @@ write_data()
dbglog((LOG_ERR, "write request " ULL_FMT " bytes at " ULL_FMT " + "
ULL_FMT " = " ULL_FMT ".\n",
- req_block.length, req_block.offset, offset,
- req_block.offset + offset));
+ req_block.length, req_block.offset, image_offset,
+ req_block.offset + image_offset));
if (req_block.length > buffer_size)
{
@@ -905,7 +1169,7 @@ main(int argc, char **argv)
{
fprintf(stderr,
"devio with custom DLL support\n"
- "Copyright (C) 2005-2018 Olof Lagerkvist.\n"
+ "Copyright (C) 2005-2021 Olof Lagerkvist.\n"
"\n"
"Usage for unmanaged C/C++ DLL files:\n"
"devio --dll=dllfile;procedure other_devio_parameters ...\n"
@@ -1026,6 +1290,13 @@ main(int argc, char **argv)
#endif
}
+ if (argc >= 4 && strcmp(argv[1], "--drv") == 0)
+ {
+ drv_mode = 1;
+ argv++;
+ argc--;
+ }
+
if (argc >= 4 && strcmp(argv[1], "--novhd") == 0)
{
auto_vhd_detect = 0;
@@ -1044,14 +1315,16 @@ main(int argc, char **argv)
{
fprintf(stderr,
"devio - Device I/O Service ver " DEVIO_VERSION "\n"
- "With support for Microsoft VHD format, custom DLL files and shared memory proxy\n"
- "operation.\n"
- "Copyright (C) 2005-2018 Olof Lagerkvist.\n"
+ "With support for Microsoft VHD format, custom DLL files, shared memory proxy\n"
+ "operation and also for use with DevIO Client Driver, if installed.\n"
+ "Copyright (C) 2005-2021 Olof Lagerkvist.\n"
"\n"
"Usage:\n"
"devio [-r] tcp-port|commdev diskdev [blocks] [offset] [alignm] [buffersize]\n"
"devio [-r] tcp-port|commdev diskdev [partitionnumber] [alignm] [buffersize]\n"
"\n"
+ "-r Open image file in read-only mode.\n"
+ "\n"
"tcp-port can be any free tcp port where this service should listen for incoming\n"
"client connections.\n"
"\n"
@@ -1059,7 +1332,8 @@ main(int argc, char **argv)
"service should listen for incoming client connections.\n"
"\n"
"commdev can also start with shm: followed by an section object name for using\n"
- "shared memory communication.\n"
+ "shared memory communication. Alternatively, drv: followed by a name for using\n"
+ "DevIO Client Driver to expose a device object connected to this devio instance.\n"
"\n"
"Default number of blocks is 0. When running on Windows the program will try to\n"
"get the size of the image file or partition automatically, otherwise the client\n"
@@ -1123,7 +1397,7 @@ main(int argc, char **argv)
void *geometry = &vhd_info.Footer.DiskGeometry;
// VHD I/O uses a secondary buffer
- buf2 = malloc(buffer_size);
+ buf2 = (char*)malloc(buffer_size);
if (buf2 == NULL)
{
syslog(LOG_ERR, "malloc() failed: %m\n");
@@ -1136,22 +1410,12 @@ main(int argc, char **argv)
current_size = GetBigEndian64(vhd_info.Footer.CurrentSize);
table_offset = GetBigEndian64(vhd_info.Header.TableOffset);
- //((longlongswap*)¤t_size)->v32.v1 =
- // ntohl(((longlongswap*)&vhd_info.Footer.CurrentSize)->v32.v2);
- //((longlongswap*)¤t_size)->v32.v2 =
- // ntohl(((longlongswap*)&vhd_info.Footer.CurrentSize)->v32.v1);
-
- //((longlongswap*)&table_offset)->v32.v1 =
- // ntohl(((longlongswap*)&vhd_info.Header.TableOffset)->v32.v2);
- //((longlongswap*)&table_offset)->v32.v2 =
- // ntohl(((longlongswap*)&vhd_info.Header.TableOffset)->v32.v1);
-
sector_size = 512;
block_size = ntohl(vhd_info.Header.BlockSize);
for (block_shift = 0;
- (block_shift < 64) &
+ (block_shift < 64) &&
((((safeio_size_t)1) << block_shift) != block_size);
block_shift++);
@@ -1167,8 +1431,9 @@ main(int argc, char **argv)
}
for (sector_shift = 0;
- (sector_shift < 64) & ((((safeio_size_t)1) << sector_shift) !=
- sector_size); sector_shift++);
+ (sector_shift < 64) &&
+ ((((safeio_size_t)1) << sector_shift) != sector_size);
+ sector_shift++);
if (argc > 3)
{
@@ -1303,7 +1568,7 @@ main(int argc, char **argv)
if (devio_info.file_size == 0)
{
struct stat file_stat = { 0 };
- if (fstat(fd, &file_stat) == 0)
+ if (fstat(image_fd, &file_stat) == 0)
devio_info.file_size = file_stat.st_size;
else
syslog(LOG_ERR, "Cannot determine size of image/partition: %m\n");
@@ -1579,7 +1844,7 @@ do_comm_shm(char *comm_device)
char *namespace_prefix;
HANDLE h = CreateFile("\\\\?\\Global", 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if ((h == INVALID_HANDLE_VALUE) & (GetLastError() == ERROR_FILE_NOT_FOUND))
+ if ((h == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_FILE_NOT_FOUND))
namespace_prefix = "";
else
namespace_prefix = "Global\\";
@@ -1620,7 +1885,7 @@ do_comm_shm(char *comm_device)
return 2;
}
- shm_view = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
+ shm_view = (char*)MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if (shm_view == NULL)
{
@@ -1645,7 +1910,7 @@ do_comm_shm(char *comm_device)
if (buf2 != NULL)
{
free(buf2);
- buf2 = malloc(buffer_size);
+ buf2 = (char*)malloc(buffer_size);
if (buf2 == NULL)
{
syslog(LOG_ERR, "malloc() failed: %m\n");
@@ -1712,6 +1977,77 @@ do_comm_shm(char *comm_device)
return 0;
}
+
+int
+do_comm_drv(char *comm_device)
+{
+ int rc;
+
+ char *objname = (char*)malloc(OBJNAME_SIZE);
+ if (objname == NULL)
+ {
+ syslog(LOG_ERR, "Memory allocation failed: %m");
+ return -1;
+ }
+
+ drv_memory_io.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ drv_request_io.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ if (drv_memory_io.hEvent == NULL || drv_request_io.hEvent == NULL)
+ {
+ syslog(LOG_ERR, "Event object create failed: %m");
+ return -1;
+ }
+
+ puts("Driver mode.");
+
+ _snprintf(objname, OBJNAME_SIZE,
+ "%ws\\%s", DEVIODRV_DEVICE_DOSDEV_NAME, comm_device);
+ objname[OBJNAME_SIZE - 1] = 0;
+
+ sd = (SOCKET)CreateFile(objname, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+
+ if (sd == INVALID_SOCKET)
+ {
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ syslog(LOG_ERR, "A service with this name is already running.\n");
+ }
+ else
+ {
+ syslog(LOG_ERR, "Error opening '%s': %m", objname);
+ }
+
+ return 2;
+ }
+
+ free(objname);
+ objname = NULL;
+
+ rc = alloc_drv_buffer();
+ if (rc > 0)
+ {
+ return rc;
+ }
+
+ drv_mode = 1;
+
+ printf("Waiting for client connection on object %s. Press Ctrl+C to cancel.\n",
+ comm_device);
+
+ ((PIMDPROXY_DEVIODRV_BUFFER_HEADER)shm_view)->request_code = IMDPROXY_REQ_INFO;
+
+ if (!send_info())
+ {
+ syslog(LOG_ERR, "Wait failed: %m.\n");
+ return 2;
+ }
+
+ printf("Connection on object %s.\n",
+ comm_device);
+
+ return 0;
+}
#endif
int
@@ -1729,11 +2065,22 @@ do_comm(char *comm_device)
#else
fprintf(stderr, "Shared memory operation only supported on Windows.\n");
return 2;
+#endif
+ }
+ else if (_strnicmp(comm_device, "drv:", 4) == 0)
+ {
+#ifdef _WIN32
+ int drvresult = do_comm_drv(comm_device + 4);
+ if (drvresult != 0)
+ return drvresult;
+#else
+ fprintf(stderr, "Driver operation only supported on Windows.\n");
+ return 2;
#endif
}
else
{
- buf = malloc(buffer_size);
+ buf = (char*)malloc(buffer_size);
if (buf == NULL)
{
syslog(LOG_ERR, "malloc() failed: %m\n");
@@ -1741,8 +2088,9 @@ do_comm(char *comm_device)
}
}
- if (shm_mode)
- ;
+ if (shm_mode || drv_mode)
+ {
+ }
else if (port != 0)
{
struct sockaddr_in saddr = { 0 };
diff --git a/devio/devio.h b/devio/devio.h
index 6f1b6f6..37eaf4b 100644
--- a/devio/devio.h
+++ b/devio/devio.h
@@ -1,21 +1,30 @@
-#define DEVIO_VERSION "3.05"
+#define DEVIO_VERSION "3.10"
-typedef safeio_ssize_t (__cdecl *dllread_proc)(void *handle,
- void *buf,
- safeio_size_t size,
- off_t_64 offset);
+#define MULTI_CONTAINER_DELIMITER ":::"
-typedef safeio_ssize_t (__cdecl *dllwrite_proc)(void *handle,
- void *buf,
- safeio_size_t size,
- off_t_64 offset);
+typedef safeio_ssize_t(__cdecl dllread_decl)(void *handle,
+ void *buf,
+ safeio_size_t size,
+ off_t_64 offset);
-typedef int (__cdecl *dllclose_proc)(void *handle);
+typedef dllread_decl *dllread_proc;
-typedef void * (__cdecl *dllopen_proc)(const char *file,
- int read_only,
- dllread_proc *dllread,
- dllwrite_proc *dllwrite,
- dllclose_proc *dllclose,
- off_t_64 *size);
+typedef safeio_ssize_t(__cdecl dllwrite_decl)(void *handle,
+ void *buf,
+ safeio_size_t size,
+ off_t_64 offset);
+typedef dllwrite_decl *dllwrite_proc;
+
+typedef int(__cdecl dllclose_decl)(void *handle);
+
+typedef dllclose_decl *dllclose_proc;
+
+typedef void * (__cdecl dllopen_decl)(const char *file,
+ int read_only,
+ dllread_proc *dllread,
+ dllwrite_proc *dllwrite,
+ dllclose_proc *dllclose,
+ off_t_64 *size);
+
+typedef dllopen_decl *dllopen_proc;
diff --git a/devio/devio.inf b/devio/devio.inf
new file mode 100644
index 0000000..9335516
--- /dev/null
+++ b/devio/devio.inf
@@ -0,0 +1,51 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = devio.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk Virtual Disk Driver Proxy back-end"
+
+
+[SourceDisksFiles.x86]
+devio.exe = 1, Release\x86
+
+[SourceDisksFiles.amd64]
+devio.exe = 1, Release\x64
+
+[SourceDisksFiles.arm]
+devio.exe = 1, Release\arm
+
+[SourceDisksFiles.arm64]
+devio.exe = 1, Release\arm64
+
+[DestinationDirs]
+ImDiskExeExeFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ImDiskExeExeFiles
+
+
+[ImDiskExeExeFiles]
+devio.exe
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDiskExe, , ImDiskExe
+
+
+[ImDiskExe]
+DisplayName = "ImDisk Virtual Disk Driver Proxy back-end"
+StartType = 2
+ServiceType = 16
+ErrorControl = 0
+ServiceBinary = %11%\devio.exe
diff --git a/devio/devio.props b/devio/devio.props
index 9088708..6b7dd21 100644
--- a/devio/devio.props
+++ b/devio/devio.props
@@ -7,6 +7,9 @@
_WINSOCK_DEPRECATED_NO_WARNINGS;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);%(PreprocessorDefinitions)
+
+ true
+
\ No newline at end of file
diff --git a/devio/devio.vcxproj b/devio/devio.vcxproj
index 075a6e2..e0aba1d 100644
--- a/devio/devio.vcxproj
+++ b/devio/devio.vcxproj
@@ -255,7 +255,7 @@
MaxSpeed
true
- WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
+ WIN32;CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
false
Level4
true
@@ -266,6 +266,7 @@
true
true
true
+ compexch.obj;%(AdditionalDependencies)
diff --git a/devio/devio_types.h b/devio/devio_types.h
index 029c5cb..1101038 100644
--- a/devio/devio_types.h
+++ b/devio/devio_types.h
@@ -1,3 +1,9 @@
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
#if defined(_MSC_VER) && _MSC_PLATFORM_TOOLSET < 120
diff --git a/devio/devioimp.props b/devio/devioimp.props
new file mode 100644
index 0000000..808f513
--- /dev/null
+++ b/devio/devioimp.props
@@ -0,0 +1,10 @@
+
+
+
+
+
+ Z:\Kod\imdisk\devio;$(IncludePath)
+
+
+
+
\ No newline at end of file
diff --git a/devio/safeio.c b/devio/safeio.c
index f95299c..0a92cd1 100644
--- a/devio/safeio.c
+++ b/devio/safeio.c
@@ -1,28 +1,28 @@
/*
- General I/O support routines for POSIX environments.
-
- Copyright (C) 2005-2007 Olof Lagerkvist.
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ General I/O support routines for POSIX environments.
+
+ Copyright (C) 2005-2007 Olof Lagerkvist.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
*/
#include
diff --git a/devio/safeio.h b/devio/safeio.h
index 0d191bf..d84bdbe 100644
--- a/devio/safeio.h
+++ b/devio/safeio.h
@@ -1,7 +1,7 @@
/*
General I/O support routines.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/devio/safeio_win32.cpp b/devio/safeio_win32.cpp
index 3c3773f..ba7e7be 100644
--- a/devio/safeio_win32.cpp
+++ b/devio/safeio_win32.cpp
@@ -1,7 +1,7 @@
/*
General I/O support routines for WIN32 environments.
- Copyright (C) 2005-2018 Olof Lagerkvist.
+ Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/devio/win32_fileio.def b/devio/win32_fileio.def
new file mode 100644
index 0000000..9a6ee83
--- /dev/null
+++ b/devio/win32_fileio.def
@@ -0,0 +1,5 @@
+LIBRARY win32_fileio.dll
+
+EXPORTS
+
+ dllopen=?dllopen@@YAPAXPBDHPAP6AHPAX1H_J@Z3PAP6AH1@ZPA_J@Z
diff --git a/devio/win32_fileio.exp b/devio/win32_fileio.exp
new file mode 100644
index 0000000..87caf72
Binary files /dev/null and b/devio/win32_fileio.exp differ
diff --git a/devio/win32_fileio.lib b/devio/win32_fileio.lib
new file mode 100644
index 0000000..bbb7715
Binary files /dev/null and b/devio/win32_fileio.lib differ
diff --git a/deviodrv/MAKEFILE b/deviodrv/MAKEFILE
new file mode 100644
index 0000000..5818975
--- /dev/null
+++ b/deviodrv/MAKEFILE
@@ -0,0 +1,7 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the driver components of the Windows NT DDK
+#
+
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/deviodrv/deviodrv.cpp b/deviodrv/deviodrv.cpp
new file mode 100644
index 0000000..907fe03
--- /dev/null
+++ b/deviodrv/deviodrv.cpp
@@ -0,0 +1,132 @@
+/*
+
+ General License for Open Source projects published by
+ Olof Lagerkvist - LTR Data.
+
+ Copyright (c) Olof Lagerkvist, LTR Data
+ http://www.ltr-data.se
+ olof@ltr-data.se
+
+ The above copyright notice shall be included in all copies or
+ substantial portions of the Software.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ As a discretionary option, the above permission notice may be
+ included in copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+#include
+#include
+
+#include "..\inc\imdisk.h"
+#include "..\inc\imdproxy.h"
+
+#include "deviodrv.h"
+
+#pragma code_seg("INIT")
+
+NTSTATUS
+DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING)
+{
+ PAGED_CODE();
+
+ KdPrint(("DevIoDrv loading.\n"));
+
+#if DBG
+
+#if (NTDDI_VERSION >= NTDDI_WS03)
+ KdRefreshDebuggerNotPresent();
+#endif
+
+ if (!KD_DEBUGGER_NOT_PRESENT)
+ DbgBreakPoint();
+#endif
+
+ InitializeListHead(&FileTable);
+
+ DriverObject->DriverUnload = DevIoDrvUnload;
+
+ UNICODE_STRING dev_path;
+ RtlInitUnicodeString(&dev_path, DEVIODRV_DEVICE_NATIVE_NAME);
+
+ PDEVICE_OBJECT DeviceObject;
+
+ NTSTATUS status = IoCreateDevice(DriverObject, 0, &dev_path, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("Failed creating device %wZ: %#x\n", &dev_path, status);
+ return status;
+ }
+ UNICODE_STRING symlink_path;
+ RtlInitUnicodeString(&symlink_path, DEVIODRV_SYMLINK_NATIVE_NAME);
+
+ status = IoCreateUnprotectedSymbolicLink(&symlink_path, &dev_path);
+ if (!NT_SUCCESS(status))
+ {
+ IoDeleteDevice(DeviceObject);
+ DbgPrint("Failed creating symlink %wZ to %wZ: %#x\n", &symlink_path, &dev_path, status);
+ return status;
+ }
+
+ DeviceObject->Flags |= DO_DIRECT_IO;
+
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = DevIoDrvDispatchCreate;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = DevIoDrvDispatchClose;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DevIoDrvDispatchCleanup;
+
+ DriverObject->MajorFunction[IRP_MJ_READ] = DevIoDrvDispatchReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = DevIoDrvDispatchReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DevIoDrvDispatchControl;
+ DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DevIoDrvDispatchControl;
+
+ DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DevIoDrvDispatchQueryInformation;
+
+ DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DevIoDrvDispatchFlushBuffers;
+
+ KdPrint(("DevIoDrv loaded.\n"));
+
+ return STATUS_SUCCESS;
+}
+
+#pragma code_seg("PAGE")
+
+void
+DevIoDrvUnload(PDRIVER_OBJECT DriverObject)
+{
+ PAGED_CODE();
+
+ KdPrint(("DevIoDrv unloading.\n"));
+
+ UNICODE_STRING symlink_path;
+ RtlInitUnicodeString(&symlink_path, DEVIODRV_SYMLINK_NATIVE_NAME);
+
+ NTSTATUS status = IoDeleteSymbolicLink(&symlink_path);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("Failed removing symlink %wZ: %#x\n", &symlink_path, status);
+ }
+
+ while (DriverObject->DeviceObject != NULL)
+ {
+#pragma warning(suppress: 6001)
+ IoDeleteDevice(DriverObject->DeviceObject);
+ }
+}
diff --git a/deviodrv/deviodrv.h b/deviodrv/deviodrv.h
new file mode 100644
index 0000000..fc38cd4
--- /dev/null
+++ b/deviodrv/deviodrv.h
@@ -0,0 +1,360 @@
+/*
+
+ General License for Open Source projects published by
+ Olof Lagerkvist - LTR Data.
+
+ Copyright (c) Olof Lagerkvist, LTR Data
+ http://www.ltr-data.se
+ olof@ltr-data.se
+
+ The above copyright notice shall be included in all copies or
+ substantial portions of the Software.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ As a discretionary option, the above permission notice may be
+ included in copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+#pragma once
+
+typedef struct _OBJECT_CONTEXT
+{
+ LIST_ENTRY ListEntry;
+
+ UNICODE_STRING Name;
+
+ LONG RefCount;
+
+ LARGE_INTEGER FileSize;
+
+ ULONG AlignmentRequirement;
+
+ ULONGLONG ServiceFlags;
+
+ PFILE_OBJECT Server;
+
+ PFILE_OBJECT Client;
+
+ KSPIN_LOCK IrpListLock;
+
+ LIST_ENTRY ServerMemoryIrpList;
+
+ LIST_ENTRY ServerRequestIrpList;
+
+ LIST_ENTRY ClientReceivedIrpList;
+
+ LIST_ENTRY ClientSentIrpList;
+
+} OBJECT_CONTEXT, *POBJECT_CONTEXT;
+
+typedef struct _IRP_QUEUE_ITEM
+{
+ LIST_ENTRY ListEntry;
+
+ PIRP Irp;
+
+ struct _IRP_QUEUE_ITEM *MemoryIrp;
+
+ PIMDPROXY_DEVIODRV_BUFFER_HEADER MappedBuffer;
+
+ ULONG MappedBufferSize;
+
+} IRP_QUEUE_ITEM, *PIRP_QUEUE_ITEM;
+
+#ifdef _NTDDK_
+
+#define POOL_TAG 'oIvD'
+
+IO_COMPLETION_ROUTINE
+DevIoDrvIoCtlCallCompletion;
+
+DRIVER_UNLOAD
+DevIoDrvUnload;
+
+EXTERN_C DRIVER_INITIALIZE
+DriverEntry;
+
+__drv_dispatchType(IRP_MJ_CREATE)
+DRIVER_DISPATCH DevIoDrvDispatchCreate;
+
+__drv_dispatchType(IRP_MJ_CREATE_NAMED_PIPE)
+DRIVER_DISPATCH DevIoDrvDispatchCreateNamedPipe;
+
+__drv_dispatchType(IRP_MJ_CLOSE)
+DRIVER_DISPATCH DevIoDrvDispatchClose;
+
+__drv_dispatchType(IRP_MJ_CLEANUP)
+DRIVER_DISPATCH DevIoDrvDispatchCleanup;
+
+__drv_dispatchType(IRP_MJ_QUERY_INFORMATION)
+DRIVER_DISPATCH DevIoDrvDispatchQueryInformation;
+
+__drv_dispatchType(IRP_MJ_SET_INFORMATION)
+DRIVER_DISPATCH DevIoDrvDispatchSetInformation;
+
+__drv_dispatchType(IRP_MJ_FLUSH_BUFFERS)
+DRIVER_DISPATCH DevIoDrvDispatchFlushBuffers;
+
+__drv_dispatchType(IRP_MJ_READ)
+__drv_dispatchType(IRP_MJ_WRITE)
+DRIVER_DISPATCH DevIoDrvDispatchReadWrite;
+
+__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
+__drv_dispatchType(IRP_MJ_FILE_SYSTEM_CONTROL)
+DRIVER_DISPATCH DevIoDrvDispatchControl;
+
+DRIVER_CANCEL DevIoDrvServerIrpCancelRoutine;
+
+NTSTATUS
+DevIoDrvOpenFileTableEntry(PFILE_OBJECT FileObject);
+
+NTSTATUS
+DevIoDrvCreateFileTableEntry(PFILE_OBJECT FileObject);
+
+NTSTATUS
+DevIoDrvCloseFileTableEntry(PFILE_OBJECT FileObject);
+
+NTSTATUS
+DevIoDrvCancelAll(PFILE_OBJECT FileObject,
+ PKIRQL LowestAssumedIrql);
+
+void
+DevIoDrvSendClientRequestToServer(POBJECT_CONTEXT File,
+ PIRP_QUEUE_ITEM ClientItem,
+ PIRP_QUEUE_ITEM ServerItem,
+ NTSTATUS *ClientStatus,
+ NTSTATUS *ServerStatus,
+ PKIRQL LowestAssumedIrql);
+
+NTSTATUS
+DevIoDrvDispatchServerLockMemory(PIRP Irp,
+ PKIRQL LowestAssumedIrql);
+
+NTSTATUS
+DevIoDrvDispatchServerIORequest(PIRP Irp,
+ PKIRQL LowestAssumedIrql);
+
+NTSTATUS
+DevIoDrvDispatchClientRequest(PIRP Irp,
+ PKIRQL LowestAssumedIrql);
+
+void
+DevIoDrvCompleteIrpQueueItem(PIRP_QUEUE_ITEM Item,
+ NTSTATUS Status,
+ ULONG_PTR Length,
+ PKIRQL LowestAssumedIrql);
+
+void
+DevIoDrvCompleteIrp(PIRP Irp,
+ NTSTATUS Status,
+ ULONG_PTR Length);
+
+NTSTATUS
+DevIoDrvReserveMemoryIrp(PIRP RequestIrp,
+ PIRP_QUEUE_ITEM *MemoryIrp,
+ PIMDPROXY_DEVIODRV_BUFFER_HEADER *MemoryBuffer,
+ PULONG BufferSize,
+ PKIRQL LowestAssumedIrql);
+
+void
+DevIoDrvQueueMemoryIrpUnsafe(PIRP_QUEUE_ITEM MemoryIrp,
+ POBJECT_CONTEXT Context);
+
+void
+DevIoDrvQueueMemoryIrp(PIRP_QUEUE_ITEM MemoryIrp,
+ POBJECT_CONTEXT Context,
+ PKIRQL LowestAssumedIrql);
+
+extern LIST_ENTRY FileTable;
+
+//
+// Optimized spin lock functions
+//
+
+#if _WIN32_WINNT >= 0x0502
+
+FORCEINLINE
+VOID
+__drv_maxIRQL(DISPATCH_LEVEL)
+__drv_when(LowestAssumedIrql < DISPATCH_LEVEL, __drv_savesIRQLGlobal(QueuedSpinLock, LockHandle))
+ __drv_when(LowestAssumedIrql < DISPATCH_LEVEL, __drv_setsIRQL(DISPATCH_LEVEL))
+ DevIoDrvAcquireLock_x64(__inout PKSPIN_LOCK SpinLock,
+ __out __deref __drv_acquiresExclusiveResource(KeQueuedSpinLockType)
+ PKLOCK_QUEUE_HANDLE LockHandle,
+ __in KIRQL LowestAssumedIrql)
+{
+ if (LowestAssumedIrql >= DISPATCH_LEVEL)
+ {
+ ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+
+ KeAcquireInStackQueuedSpinLockAtDpcLevel(SpinLock, LockHandle);
+ }
+ else
+ {
+ KeAcquireInStackQueuedSpinLock(SpinLock, LockHandle);
+ }
+}
+
+FORCEINLINE
+VOID
+__drv_requiresIRQL(DISPATCH_LEVEL)
+__drv_when(*LowestAssumedIrql < DISPATCH_LEVEL, __drv_restoresIRQLGlobal(QueuedSpinLock, LockHandle))
+ DevIoDrvReleaseLock_x64(
+ __in __deref __drv_releasesExclusiveResource(KeQueuedSpinLockType)
+ PKLOCK_QUEUE_HANDLE LockHandle,
+ __inout PKIRQL LowestAssumedIrql)
+{
+ ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+
+ if (*LowestAssumedIrql >= DISPATCH_LEVEL)
+ {
+ KeReleaseInStackQueuedSpinLockFromDpcLevel(LockHandle);
+ }
+ else
+ {
+ KeReleaseInStackQueuedSpinLock(LockHandle);
+ *LowestAssumedIrql = LockHandle->OldIrql;
+ }
+}
+
+#endif
+
+FORCEINLINE
+VOID
+__drv_maxIRQL(DISPATCH_LEVEL)
+__drv_when(LowestAssumedIrql < DISPATCH_LEVEL, __drv_setsIRQL(DISPATCH_LEVEL))
+ DevIoDrvAcquireLock_x86(__inout __deref __drv_acquiresExclusiveResource(KeSpinLockType) PKSPIN_LOCK SpinLock,
+ __drv_when(LowestAssumedIrql < DISPATCH_LEVEL, __out __deref __drv_savesIRQL) PKIRQL OldIrql,
+ __in KIRQL LowestAssumedIrql)
+{
+ if (LowestAssumedIrql >= DISPATCH_LEVEL)
+ {
+ ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+
+ KeAcquireSpinLockAtDpcLevel(SpinLock);
+ }
+ else
+ {
+ KeAcquireSpinLock(SpinLock, OldIrql);
+ }
+}
+
+FORCEINLINE
+VOID
+__drv_requiresIRQL(DISPATCH_LEVEL)
+DevIoDrvReleaseLock_x86(
+ __inout __deref __drv_releasesExclusiveResource(KeSpinLockType) PKSPIN_LOCK SpinLock,
+ __in __drv_when(*LowestAssumedIrql < DISPATCH_LEVEL, __drv_restoresIRQL) KIRQL OldIrql,
+ __inout __deref PKIRQL LowestAssumedIrql)
+{
+ ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+
+ if (*LowestAssumedIrql >= DISPATCH_LEVEL)
+ {
+ KeReleaseSpinLockFromDpcLevel(SpinLock);
+ }
+ else
+ {
+ KeReleaseSpinLock(SpinLock, OldIrql);
+ *LowestAssumedIrql = OldIrql;
+ }
+}
+
+#ifdef _AMD64_
+
+#define DevIoDrvAcquireLock DevIoDrvAcquireLock_x64
+
+#define DevIoDrvReleaseLock DevIoDrvReleaseLock_x64
+
+#else
+
+#define DevIoDrvAcquireLock(SpinLock, LockHandle, LowestAssumedIrql) \
+ { \
+ (LockHandle)->LockQueue.Lock = (SpinLock); \
+ DevIoDrvAcquireLock_x86((LockHandle)->LockQueue.Lock, &(LockHandle)->OldIrql, (LowestAssumedIrql)); \
+ }
+
+#define DevIoDrvReleaseLock(LockHandle, LowestAssumedIrql) \
+ { \
+ DevIoDrvReleaseLock_x86((LockHandle)->LockQueue.Lock, (LockHandle)->OldIrql, (LowestAssumedIrql)); \
+ }
+
+#endif
+
+FORCEINLINE
+VOID
+DevIoDrvInterlockedInsertTailList(
+ PLIST_ENTRY ListHead,
+ PLIST_ENTRY ListEntry,
+ PKSPIN_LOCK SpinLock,
+ PKIRQL LowestAssumedIrql)
+{
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ DevIoDrvAcquireLock(SpinLock, &lock_handle, *LowestAssumedIrql);
+
+ InsertTailList(ListHead, ListEntry);
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+}
+
+FORCEINLINE
+VOID
+DevIoDrvInterlockedInsertHeadList(
+ PLIST_ENTRY ListHead,
+ PLIST_ENTRY ListEntry,
+ PKSPIN_LOCK SpinLock,
+ PKIRQL LowestAssumedIrql)
+{
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ DevIoDrvAcquireLock(SpinLock, &lock_handle, *LowestAssumedIrql);
+
+ InsertHeadList(ListHead, ListEntry);
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+}
+
+FORCEINLINE
+PLIST_ENTRY
+DevIoDrvInterlockedRemoveHeadList(
+ PLIST_ENTRY ListHead,
+ PKSPIN_LOCK SpinLock,
+ PKIRQL LowestAssumedIrql)
+{
+ KLOCK_QUEUE_HANDLE lock_handle;
+ PLIST_ENTRY item;
+
+ DevIoDrvAcquireLock(SpinLock, &lock_handle, *LowestAssumedIrql);
+
+ item = RemoveHeadList(ListHead);
+
+ if (item == ListHead)
+ {
+ item = NULL;
+ }
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ return item;
+}
+
+#endif
diff --git a/deviodrv/deviodrv.inf b/deviodrv/deviodrv.inf
new file mode 100644
index 0000000..bc85bbd
--- /dev/null
+++ b/deviodrv/deviodrv.inf
@@ -0,0 +1,54 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = deviodrv.cat
+
+
+[SourceDisksNames]
+1 = "DevIO Client Driver"
+
+
+[SourceDisksFiles.x86]
+deviodrv.sys = 1, i386
+
+[SourceDisksFiles.ia64]
+deviodrv.sys = 1, ia64
+
+[SourceDisksFiles.amd64]
+deviodrv.sys = 1, amd64
+
+[SourceDisksFiles.arm]
+deviodrv.sys = 1, arm
+
+[SourceDisksFiles.arm64]
+deviodrv.sys = 1, arm64
+
+[DestinationDirs]
+DevIoDrvSysFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = DevIoDrvSysFiles
+
+
+[DevIoDrvSysFiles]
+deviodrv.sys
+
+
+[DefaultInstall.ntx86.Services]
+AddService = DevIoDrv, , DevIoDrvDrv
+
+
+[DevIoDrvDrv]
+DisplayName = "DevIO Client Driver"
+StartType = 2
+ServiceType = 1
+ErrorControl = 0
+ServiceBinary = %12%\DevIoDrv.sys
diff --git a/deviodrv/deviodrv.rc b/deviodrv/deviodrv.rc
new file mode 100644
index 0000000..79a270e
--- /dev/null
+++ b/deviodrv/deviodrv.rc
@@ -0,0 +1,43 @@
+#define UNICODE
+#define _UNICODE
+#include
+
+#include "..\inc\imdiskver.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION IMDISK_RC_VERSION_FLD,1
+PRODUCTVERSION IMDISK_RC_VERSION_FLD,1
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifndef DEBUG
+ FILEFLAGS 0
+#else
+ FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
+#endif
+FILEOS VOS_NT
+FILETYPE VFT_DRV
+FILESUBTYPE VFT2_DRV_INSTALLABLE
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Olof Lagerkvist\0"
+ VALUE "FileDescription", "DevIO Client Driver\0"
+ VALUE "FileVersion", IMDISK_RC_VERSION_STR ".1\0"
+ VALUE "InternalName", "deviodrv\0"
+ VALUE "LegalCopyright", "Copyright © 2019 Olof Lagerkvist.\0"
+ VALUE "OriginalFilename", "deviodrv.sys\0"
+ VALUE "ProductName", "deviodrv\0"
+ VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".1\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/deviodrv/deviodrv.vcxproj b/deviodrv/deviodrv.vcxproj
new file mode 100644
index 0000000..ac5554d
--- /dev/null
+++ b/deviodrv/deviodrv.vcxproj
@@ -0,0 +1,193 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM
+
+
+ Release
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {457B6C05-3FED-4056-A4B3-B1B110242F14}
+ {dd38f7fc-d7bd-488b-9242-7d8754cde80d}
+ 12.0
+ Debug
+ Win32
+ deviodrv
+ $(LatestTargetPlatformVersion)
+
+
+
+ true
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ false
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ true
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ false
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ true
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ false
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ WDM
+
+
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ WDM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DbgengKernelDebugger
+ $(ConfigurationName)\$(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(ConfigurationName)\$(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(ConfigurationName)\$(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(ConfigurationName)\$(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+ DbgengKernelDebugger
+ $(InfArch)\
+ $(ConfigurationName)\$(InfArch)\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/deviodrv/dispatch.cpp b/deviodrv/dispatch.cpp
new file mode 100644
index 0000000..105e514
--- /dev/null
+++ b/deviodrv/dispatch.cpp
@@ -0,0 +1,451 @@
+/*
+
+ General License for Open Source projects published by
+ Olof Lagerkvist - LTR Data.
+
+ Copyright (c) Olof Lagerkvist, LTR Data
+ http://www.ltr-data.se
+ olof@ltr-data.se
+
+ The above copyright notice shall be included in all copies or
+ substantial portions of the Software.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ As a discretionary option, the above permission notice may be
+ included in copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+#include
+#include
+
+#include "..\inc\imdisk.h"
+#include "..\inc\imdproxy.h"
+#include "..\inc\ntkmapi.h"
+
+#include "deviodrv.h"
+
+NTSTATUS
+DevIoDrvDispatchCreate(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+
+ Irp->IoStatus.Information = 0;
+
+ union CREATE_OPTIONS
+ {
+ struct
+ {
+ ULONG CreateOptions : 24;
+ ULONG CreateDisposition : 8;
+ };
+ ULONG Options;
+ } Options;
+ Options.Options = io_stack->Parameters.Create.Options;
+
+ KdPrint(("Creating handle for '%wZ' FileObject=%p DesiredAccess=%#x CreateDisposition=%#x CreateOptions=%#x Flags=%#x\n",
+ &io_stack->FileObject->FileName, io_stack->FileObject, io_stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Options.CreateDisposition, Options.CreateOptions, io_stack->FileObject->Flags));
+
+ NTSTATUS status;
+
+ if (Options.CreateDisposition == FILE_CREATE) // Create server end
+ {
+ status = DevIoDrvCreateFileTableEntry(io_stack->FileObject);
+
+ if (status == STATUS_SUCCESS)
+ {
+ Irp->IoStatus.Information = FILE_CREATED;
+ }
+ else if (status == STATUS_OBJECT_NAME_COLLISION)
+ {
+ Irp->IoStatus.Information = FILE_EXISTS;
+ }
+ }
+ else if (Options.CreateDisposition == FILE_OPEN) // Open client end
+ {
+ status = DevIoDrvOpenFileTableEntry(io_stack->FileObject);
+
+ if (status == STATUS_SUCCESS)
+ {
+ Irp->IoStatus.Information = FILE_OPENED;
+ }
+ else if (status == STATUS_OBJECT_NAME_NOT_FOUND ||
+ status == STATUS_SHARING_VIOLATION)
+ {
+ Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
+ }
+ }
+ else
+ {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ Irp->IoStatus.Status = status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DevIoDrvDispatchClose(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ KdPrint(("Closing handle for FileObject=%p Name='%wZ'\n",
+ io_stack->FileObject, &((POBJECT_CONTEXT)io_stack->FileObject->FsContext2)->Name));
+
+ while (!NT_SUCCESS(DevIoDrvCloseFileTableEntry(io_stack->FileObject)))
+ {
+ LARGE_INTEGER interval;
+ interval.QuadPart = -200000;
+ KeDelayExecutionThread(KernelMode, TRUE, &interval);
+ }
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+DevIoDrvDispatchCleanup(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+
+ Irp->IoStatus.Information = 0;
+
+ KdPrint(("IRP=%p Cleanup request for FileObject=%p Name='%wZ'\n",
+ Irp, io_stack->FileObject, &((POBJECT_CONTEXT)io_stack->FileObject->FsContext2)->Name));
+
+ KIRQL lowest_assumed_irql = PASSIVE_LEVEL;
+
+ NTSTATUS status = DevIoDrvCancelAll(io_stack->FileObject, &lowest_assumed_irql);
+
+ Irp->IoStatus.Status = status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DevIoDrvDispatchControl(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ if (context == NULL ||
+ (io_stack->MajorFunction != IRP_MJ_DEVICE_CONTROL &&
+ !(io_stack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
+ (io_stack->MinorFunction == IRP_MN_KERNEL_CALL ||
+ io_stack->MinorFunction == IRP_MN_USER_FS_REQUEST))))
+ {
+ DevIoDrvCompleteIrp(Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
+
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ Irp->IoStatus.Information = 0;
+
+ KIRQL lowest_assumed_irql = PASSIVE_LEVEL;
+
+ NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
+
+ switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case FSCTL_SET_ZERO_DATA:
+ {
+ PFILE_ZERO_DATA_INFORMATION zero = (PFILE_ZERO_DATA_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ if (io_stack->Parameters.FileSystemControl.InputBufferLength != sizeof FILE_ZERO_DATA_INFORMATION ||
+ zero->BeyondFinalZero.QuadPart < zero->FileOffset.QuadPart)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return DevIoDrvDispatchClientRequest(Irp, &lowest_assumed_irql);
+ }
+
+ case FSCTL_FILE_LEVEL_TRIM:
+ {
+ PFILE_LEVEL_TRIM trim = (PFILE_LEVEL_TRIM)Irp->AssociatedIrp.SystemBuffer;
+
+ if (io_stack->Parameters.FileSystemControl.InputBufferLength < sizeof FILE_LEVEL_TRIM ||
+ io_stack->Parameters.FileSystemControl.InputBufferLength <
+ FIELD_OFFSET(FILE_LEVEL_TRIM, Ranges) + trim->NumRanges * (ULONGLONG)sizeof(*trim->Ranges))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return DevIoDrvDispatchClientRequest(Irp, &lowest_assumed_irql);
+ }
+
+ case IOCTL_DEVIODRV_EXCHANGE_IO:
+ {
+ if (context->Server != io_stack->FileObject)
+ {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ return DevIoDrvDispatchServerIORequest(Irp, &lowest_assumed_irql);
+ }
+
+ case IOCTL_DEVIODRV_LOCK_MEMORY:
+ {
+ if (context->Server != io_stack->FileObject)
+ {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ return DevIoDrvDispatchServerLockMemory(Irp, &lowest_assumed_irql);
+ }
+ }
+
+ Irp->IoStatus.Status = status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DevIoDrvDispatchSetInformation(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+
+ Irp->IoStatus.Information = 0;
+
+ NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
+
+ switch (io_stack->Parameters.SetFile.FileInformationClass)
+ {
+ case FilePositionInformation:
+ {
+ PFILE_POSITION_INFORMATION position_info =
+ (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ if (io_stack->Parameters.SetFile.Length <
+ sizeof(FILE_POSITION_INFORMATION))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (io_stack->FileObject != NULL)
+ {
+ io_stack->FileObject->CurrentByteOffset =
+ position_info->CurrentByteOffset;
+ }
+
+ status = STATUS_SUCCESS;
+ break;
+ }
+
+ case FileBasicInformation:
+ case FileDispositionInformation:
+ case FileValidDataLengthInformation:
+ status = STATUS_SUCCESS;
+ break;
+
+ default:
+ {
+ KdPrint(("DevIoDrv: Unknown SetInformation function %#x.\n",
+ io_stack->Parameters.SetFile.FileInformationClass));
+
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+ }
+
+ Irp->IoStatus.Status = status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DevIoDrvDispatchReadWrite(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+
+ Irp->IoStatus.Information = 0;
+
+ KdPrint(("IRP=%p Read for FileObject=%p\n", Irp, io_stack->FileObject));
+
+ if ((io_stack->Parameters.Read.ByteOffset.QuadPart < 0) ||
+ ((io_stack->Parameters.Read.ByteOffset.QuadPart +
+ io_stack->Parameters.Read.Length) < 0))
+ {
+ KdPrint(("DevIoDrv: Read/write attempt on negative offset.\n"));
+
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ NTSTATUS status;
+
+ KIRQL lowest_assumed_irql = PASSIVE_LEVEL;
+
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ if (context == NULL)
+ {
+ status = STATUS_INTERNAL_ERROR;
+ }
+ else if (context->Server == NULL)
+ {
+ KdPrint(("DevIoDrv: IRP=%p Request to disconnected device.\n", Irp));
+
+ status = STATUS_DEVICE_DOES_NOT_EXIST;
+ }
+ else if (io_stack->MajorFunction == IRP_MJ_READ &&
+ io_stack->Parameters.Read.Length == 0 &&
+ io_stack->Parameters.Read.ByteOffset.QuadPart < context->FileSize.QuadPart)
+ {
+ status = STATUS_SUCCESS;
+ }
+ else if (io_stack->MajorFunction == IRP_MJ_WRITE &&
+ FlagOn(context->ServiceFlags, IMDPROXY_FLAG_RO))
+ {
+ status = STATUS_MEDIA_WRITE_PROTECTED;
+ }
+ else if (io_stack->MajorFunction == IRP_MJ_WRITE &&
+ io_stack->Parameters.Write.Length == 0 &&
+ io_stack->Parameters.Write.ByteOffset.QuadPart < context->FileSize.QuadPart)
+ {
+ status = STATUS_SUCCESS;
+ }
+ else if (context->Client == io_stack->FileObject ||
+ context->Server == io_stack->FileObject)
+ {
+ return DevIoDrvDispatchClientRequest(Irp, &lowest_assumed_irql);
+ }
+ else
+ {
+ status = STATUS_INTERNAL_ERROR;
+ }
+
+ Irp->IoStatus.Status = status;
+
+ IoCompleteRequest(Irp, status == STATUS_SUCCESS ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DevIoDrvDispatchQueryInformation(PDEVICE_OBJECT, PIRP Irp)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ KdPrint(("IRP=%p Query information for '%wZ' FileObject=%p\n",
+ Irp, &context->Name, io_stack->FileObject));
+
+ Irp->IoStatus.Information = 0;
+
+ NTSTATUS status;
+
+ status = STATUS_INVALID_DEVICE_REQUEST;
+
+ if (context == NULL)
+ {
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+ }
+
+ switch (io_stack->Parameters.QueryFile.FileInformationClass)
+ {
+ case FileStandardInformation:
+ {
+ PFILE_STANDARD_INFORMATION standard_info =
+ (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ if (io_stack->Parameters.QueryFile.Length < sizeof(FILE_STANDARD_INFORMATION))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ standard_info->AllocationSize =
+ standard_info->EndOfFile = context->FileSize;
+
+ Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
+ status = STATUS_SUCCESS;
+ break;
+ }
+
+ case FilePositionInformation:
+ {
+ PFILE_POSITION_INFORMATION position_info =
+ (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ if (io_stack->Parameters.QueryFile.Length <
+ sizeof(FILE_POSITION_INFORMATION))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ position_info->CurrentByteOffset =
+ io_stack->FileObject->CurrentByteOffset;
+
+ Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
+
+ status = STATUS_SUCCESS;
+ break;
+ }
+
+ default:
+ KdPrint(("DevIoDrv: Unknown QueryInformation function %#x.\n",
+ io_stack->Parameters.QueryFile.FileInformationClass));
+
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DevIoDrvDispatchFlushBuffers(PDEVICE_OBJECT, PIRP Irp)
+{
+ KdPrint(("IRP=%p Flush buffers for FileObject=%p\n",
+ Irp, IoGetCurrentIrpStackLocation(Irp)->FileObject));
+
+ DevIoDrvCompleteIrp(Irp, STATUS_SUCCESS, 0);
+
+ return STATUS_SUCCESS;
+}
+
diff --git a/deviodrv/filetable.cpp b/deviodrv/filetable.cpp
new file mode 100644
index 0000000..5d16ded
--- /dev/null
+++ b/deviodrv/filetable.cpp
@@ -0,0 +1,211 @@
+/*
+
+ General License for Open Source projects published by
+ Olof Lagerkvist - LTR Data.
+
+ Copyright (c) Olof Lagerkvist, LTR Data
+ http://www.ltr-data.se
+ olof@ltr-data.se
+
+ The above copyright notice shall be included in all copies or
+ substantial portions of the Software.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ As a discretionary option, the above permission notice may be
+ included in copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+#include
+#include
+#include
+
+#include "..\inc\imdisk.h"
+#include "..\inc\imdproxy.h"
+#include "..\inc\ntkmapi.h"
+
+#include "deviodrv.h"
+
+#pragma code_seg("PAGE")
+
+LIST_ENTRY FileTable;
+
+LONG FileTableListLock;
+
+NTSTATUS DevIoDrvOpenFileTableEntry(PFILE_OBJECT FileObject)
+{
+ PAGED_CODE();
+
+ if (InterlockedExchange(&FileTableListLock, 1) != 0)
+ {
+ return STATUS_DEVICE_BUSY;
+ }
+
+ PLIST_ENTRY entry = FileTable.Flink;
+
+ NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
+
+ POBJECT_CONTEXT context;
+
+ while (entry != &FileTable)
+ {
+ context = CONTAINING_RECORD(entry, OBJECT_CONTEXT, ListEntry);
+
+ if (RtlEqualUnicodeString(&FileObject->FileName, &context->Name, TRUE))
+ {
+ if (InterlockedIncrement(&context->RefCount) != 2)
+ {
+ status = STATUS_SHARING_VIOLATION;
+ }
+ else
+ {
+ context->Client = FileObject;
+ FileObject->FsContext2 = context;
+ status = STATUS_SUCCESS;
+ }
+
+ break;
+ }
+
+ entry = entry->Flink;
+ }
+
+ InterlockedExchange(&FileTableListLock, 0);
+
+ return status;
+}
+
+NTSTATUS DevIoDrvCreateFileTableEntry(PFILE_OBJECT FileObject)
+{
+ PAGED_CODE();
+
+ if (InterlockedExchange(&FileTableListLock, 1) != 0)
+ {
+ return STATUS_DEVICE_BUSY;
+ }
+
+ PLIST_ENTRY entry = FileTable.Flink;
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ POBJECT_CONTEXT context = NULL;
+
+ while (entry != &FileTable)
+ {
+ context = CONTAINING_RECORD(entry, OBJECT_CONTEXT, ListEntry);
+
+ if (RtlEqualUnicodeString(&FileObject->FileName, &context->Name, TRUE))
+ {
+ status = STATUS_OBJECT_NAME_COLLISION;
+ break;
+ }
+
+ entry = entry->Flink;
+ }
+
+ if (NT_SUCCESS(status))
+ {
+ context = (POBJECT_CONTEXT)ExAllocatePoolWithTag(NonPagedPool, sizeof OBJECT_CONTEXT, POOL_TAG);
+
+ if (context == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ if (NT_SUCCESS(status))
+ {
+ RtlZeroMemory(context, sizeof OBJECT_CONTEXT);
+
+ context->Name.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, FileObject->FileName.Length, POOL_TAG);
+
+ if (context->Name.Buffer == NULL)
+ {
+ ExFreePoolWithTag(context, POOL_TAG);
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ if (NT_SUCCESS(status))
+ {
+ context->Name.MaximumLength = context->Name.Length = FileObject->FileName.Length;
+ RtlCopyUnicodeString(&context->Name, &FileObject->FileName);
+
+ KeInitializeSpinLock(&context->IrpListLock);
+ InitializeListHead(&context->ServerRequestIrpList);
+ InitializeListHead(&context->ServerMemoryIrpList);
+ InitializeListHead(&context->ClientReceivedIrpList);
+ InitializeListHead(&context->ClientSentIrpList);
+
+ context->Server = FileObject;
+ context->RefCount = 1;
+ FileObject->FsContext2 = context;
+
+ InsertHeadList(&FileTable, &context->ListEntry);
+ }
+
+ InterlockedExchange(&FileTableListLock, 0);
+
+ return status;
+}
+
+NTSTATUS DevIoDrvCloseFileTableEntry(PFILE_OBJECT FileObject)
+{
+ PAGED_CODE();
+
+ if (InterlockedExchange(&FileTableListLock, 1) != 0)
+ {
+ return STATUS_RESOURCE_IN_USE;
+ }
+
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)FileObject->FsContext2;
+
+ if (FileObject == context->Server)
+ {
+ context->Server = NULL;
+ }
+ else if (FileObject == context->Client)
+ {
+ context->Client = NULL;
+ }
+
+ if (InterlockedDecrement(&context->RefCount) > 0)
+ {
+ KdPrint(("Reference to file '%wZ' closing. Not last reference.\n", &context->Name));
+
+ InterlockedExchange(&FileTableListLock, 0);
+ return STATUS_SUCCESS;
+ }
+
+ KdPrint(("Last reference to file '%wZ' closing.\n", &context->Name));
+
+ RemoveEntryList(&context->ListEntry);
+
+ FileObject->FsContext2 = NULL;
+
+ InterlockedExchange(&FileTableListLock, 0);
+
+ ExFreePoolWithTag(context->Name.Buffer, POOL_TAG);
+
+ ExFreePoolWithTag(context, POOL_TAG);
+
+ return STATUS_SUCCESS;
+}
+
diff --git a/deviodrv/irpfwd.cpp b/deviodrv/irpfwd.cpp
new file mode 100644
index 0000000..18cf0ed
--- /dev/null
+++ b/deviodrv/irpfwd.cpp
@@ -0,0 +1,960 @@
+/*
+
+ General License for Open Source projects published by
+ Olof Lagerkvist - LTR Data.
+
+ Copyright (c) Olof Lagerkvist, LTR Data
+ http://www.ltr-data.se
+ olof@ltr-data.se
+
+ The above copyright notice shall be included in all copies or
+ substantial portions of the Software.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ As a discretionary option, the above permission notice may be
+ included in copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+#include
+#include
+#include
+
+#include "..\inc\imdisk.h"
+#include "..\inc\imdproxy.h"
+#include "..\inc\ntkmapi.h"
+
+#include "deviodrv.h"
+
+NTSTATUS
+DevIoDrvCancelAll(PFILE_OBJECT FileObject,
+ PKIRQL LowestAssumedIrql)
+{
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)FileObject->FsContext2;
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ KdPrint(("Request to cancel all pending IRPs for FileObject=%p.\n",
+ FileObject));
+
+ context->Server = NULL;
+
+ DevIoDrvAcquireLock(&context->IrpListLock, &lock_handle, *LowestAssumedIrql);
+
+ KIRQL raised_irql = DISPATCH_LEVEL;
+
+ for (;;)
+ {
+ KIRQL cancel_irql;
+ IoAcquireCancelSpinLock(&cancel_irql);
+
+ PLIST_ENTRY entry = RemoveHeadList(&context->ServerRequestIrpList);
+
+ if (entry == &context->ServerRequestIrpList)
+ {
+ entry = RemoveHeadList(&context->ServerMemoryIrpList);
+
+ if (entry == &context->ServerMemoryIrpList)
+ {
+ IoReleaseCancelSpinLock(cancel_irql);
+ break;
+ }
+ }
+
+ PIRP_QUEUE_ITEM item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+
+ IoSetCancelRoutine(item->Irp, NULL);
+
+ IoReleaseCancelSpinLock(cancel_irql);
+
+ if (item->MemoryIrp != NULL)
+ {
+ item->MappedBuffer = NULL;
+
+ for (PLIST_ENTRY mem_entry = context->ServerMemoryIrpList.Flink;
+ mem_entry != &context->ServerMemoryIrpList;
+ mem_entry = mem_entry->Flink)
+ {
+ PIRP_QUEUE_ITEM mem_item = CONTAINING_RECORD(mem_entry, IRP_QUEUE_ITEM, ListEntry);
+
+ if (mem_item == item->MemoryIrp)
+ {
+ item->MappedBuffer = mem_item->MappedBuffer;
+ item->MappedBufferSize = mem_item->MappedBufferSize;
+ break;
+ }
+ }
+
+ item->MemoryIrp = NULL;
+ }
+
+ //KdPrint(("Closing server connection '%wZ' IRP=%p\n", &context->Name, item->Irp));
+
+ if (item->MappedBuffer == NULL)
+ {
+ DevIoDrvCompleteIrpQueueItem(item, STATUS_DEVICE_DOES_NOT_EXIST, 0, &raised_irql);
+ }
+ else
+ {
+ item->MappedBuffer->request_code = IMDPROXY_REQ_CLOSE;
+ item->MappedBuffer->io_tag = 0;
+ PIMDPROXY_CLOSE_REQ header = (PIMDPROXY_CLOSE_REQ)(item->MappedBuffer + 1);
+ header->request_code = IMDPROXY_REQ_CLOSE;
+ DevIoDrvCompleteIrpQueueItem(item, STATUS_SUCCESS, IMDPROXY_HEADER_SIZE, &raised_irql);
+ }
+ }
+
+ while (!IsListEmpty(&context->ClientReceivedIrpList))
+ {
+ PLIST_ENTRY entry = context->ClientReceivedIrpList.Flink;
+ PIRP_QUEUE_ITEM item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+
+ KdPrint(("Canceling received client IRP=%p\n", item->Irp));
+
+ RemoveEntryList(entry);
+
+ DevIoDrvCompleteIrpQueueItem(item, STATUS_DEVICE_DOES_NOT_EXIST, 0, &raised_irql);
+ }
+
+ while (!IsListEmpty(&context->ClientSentIrpList))
+ {
+ PLIST_ENTRY entry = context->ClientSentIrpList.Flink;
+ PIRP_QUEUE_ITEM item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+
+ KdPrint(("Canceling processed client IRP=%p\n", item->Irp));
+
+ RemoveEntryList(entry);
+
+ DevIoDrvCompleteIrpQueueItem(item, STATUS_DEVICE_DOES_NOT_EXIST, 0, &raised_irql);
+ }
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ return STATUS_SUCCESS;
+}
+
+PIRP_QUEUE_ITEM
+DevIoDrvGetSentClientRequest(POBJECT_CONTEXT File,
+ ULONGLONG Tag,
+ PKIRQL LowestAssumedIrql)
+{
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ PIRP_QUEUE_ITEM found_item = NULL;
+
+ DevIoDrvAcquireLock(&File->IrpListLock, &lock_handle, *LowestAssumedIrql);
+
+ for (PLIST_ENTRY entry = File->ClientSentIrpList.Flink; entry != &File->ClientSentIrpList; entry = entry->Flink)
+ {
+ if ((ULONGLONG)(ULONG_PTR)entry == Tag)
+ {
+ RemoveEntryList(entry);
+ found_item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+ break;
+ }
+ }
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ return found_item;
+}
+
+void
+DevIoDrvCompleteIrpQueueItem(PIRP_QUEUE_ITEM Item,
+ NTSTATUS Status,
+ ULONG_PTR Length,
+ PKIRQL LowestAssumedIrql)
+{
+ if (Status == STATUS_BUFFER_TOO_SMALL &&
+ Item->MemoryIrp != NULL)
+ {
+ DevIoDrvCompleteIrpQueueItem(Item->MemoryIrp, Status, Length, LowestAssumedIrql);
+ Item->MemoryIrp = NULL;
+ }
+ else if (Item->MemoryIrp != NULL)
+ {
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)
+ IoGetCurrentIrpStackLocation(Item->Irp)->FileObject->FsContext2;
+
+ DevIoDrvQueueMemoryIrp(Item->MemoryIrp, context, LowestAssumedIrql);
+ }
+
+ DevIoDrvCompleteIrp(Item->Irp, Status, Length);
+
+ ExFreePoolWithTag(Item, POOL_TAG);
+}
+
+void
+DevIoDrvCompleteIrp(PIRP Irp,
+ NTSTATUS Status,
+ ULONG_PTR Length)
+{
+ KdPrint(("Completing IRP=%p with status %#x\n", Irp, Status));
+
+ Irp->IoStatus.Information = Length;
+ Irp->IoStatus.Status = Status;
+
+ IoCompleteRequest(Irp, Status == STATUS_SUCCESS ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
+}
+
+NTSTATUS
+DevIoDrvReserveMemoryIrp(PIRP RequestIrp,
+ PIRP_QUEUE_ITEM *MemoryIrp,
+ PIMDPROXY_DEVIODRV_BUFFER_HEADER *MemoryBuffer,
+ PULONG BufferSize,
+ PKIRQL LowestAssumedIrql)
+{
+ *MemoryIrp = NULL;
+ *MemoryBuffer = NULL;
+ *BufferSize = 0;
+
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(RequestIrp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ if (io_stack->Parameters.DeviceIoControl.OutputBufferLength > 0)
+ {
+ *MemoryBuffer =
+ (PIMDPROXY_DEVIODRV_BUFFER_HEADER)MmGetSystemAddressForMdlSafe(RequestIrp->MdlAddress,
+ NormalPagePriority);
+
+ if (*MemoryBuffer != NULL)
+ {
+ *BufferSize = io_stack->Parameters.DeviceIoControl.OutputBufferLength;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ if (io_stack->Parameters.DeviceIoControl.InputBufferLength == 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ DevIoDrvAcquireLock(&context->IrpListLock, &lock_handle, *LowestAssumedIrql);
+
+ for (PLIST_ENTRY entry = context->ServerMemoryIrpList.Flink; entry != &context->ServerMemoryIrpList; entry = entry->Flink)
+ {
+ PIRP_QUEUE_ITEM item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+ PIO_STACK_LOCATION mem_irp_io_stack = IoGetCurrentIrpStackLocation(item->Irp);
+
+ if (io_stack->Parameters.DeviceIoControl.InputBufferLength == mem_irp_io_stack->Parameters.DeviceIoControl.InputBufferLength &&
+ RtlEqualMemory(RequestIrp->AssociatedIrp.SystemBuffer, item->Irp->AssociatedIrp.SystemBuffer,
+ io_stack->Parameters.DeviceIoControl.InputBufferLength))
+ {
+ KIRQL cancel_irql;
+
+ IoAcquireCancelSpinLock(&cancel_irql);
+
+ if (item->Irp->Cancel)
+ {
+ IoReleaseCancelSpinLock(cancel_irql);
+ continue;
+ }
+
+ IoSetCancelRoutine(item->Irp, NULL);
+
+ IoReleaseCancelSpinLock(cancel_irql);
+
+ RemoveEntryList(&item->ListEntry);
+
+ *MemoryIrp = item;
+ *MemoryBuffer = item->MappedBuffer;
+ *BufferSize = mem_irp_io_stack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ return STATUS_SUCCESS;
+ }
+ }
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ return STATUS_INVALID_PARAMETER;
+}
+
+void
+DevIoDrvQueueMemoryIrpUnsafe(PIRP_QUEUE_ITEM MemoryIrp,
+ POBJECT_CONTEXT Context)
+{
+ if (MemoryIrp == NULL)
+ {
+ return;
+ }
+
+ IoSetCancelRoutine(MemoryIrp->Irp, DevIoDrvServerIrpCancelRoutine);
+
+ IoMarkIrpPending(MemoryIrp->Irp);
+
+ InsertTailList(&Context->ServerMemoryIrpList, &MemoryIrp->ListEntry);
+}
+
+void
+DevIoDrvQueueMemoryIrp(PIRP_QUEUE_ITEM MemoryIrp,
+ POBJECT_CONTEXT Context,
+ PKIRQL LowestAssumedIrql)
+{
+ if (MemoryIrp == NULL)
+ {
+ return;
+ }
+
+ KLOCK_QUEUE_HANDLE lock_handle;
+ DevIoDrvAcquireLock(&Context->IrpListLock, &lock_handle, *LowestAssumedIrql);
+
+ KIRQL cancel_irql;
+
+ IoAcquireCancelSpinLock(&cancel_irql);
+
+ DevIoDrvQueueMemoryIrpUnsafe(MemoryIrp, Context);
+
+ IoReleaseCancelSpinLock(cancel_irql);
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+}
+
+NTSTATUS
+DevIoDrvDispatchServerLockMemory(PIRP Irp,
+ PKIRQL LowestAssumedIrql)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ KdPrint(("IRP=%p Server Memory Lock request.\n", Irp));
+
+ if (io_stack->Parameters.DeviceIoControl.OutputBufferLength < IMDPROXY_HEADER_SIZE)
+ {
+ KdPrint(("IRP=%p Buffer too small: %u.\n",
+ Irp, io_stack->Parameters.DeviceIoControl.OutputBufferLength));
+
+ DevIoDrvCompleteIrp(Irp, STATUS_BUFFER_TOO_SMALL, 0);
+
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ PIMDPROXY_DEVIODRV_BUFFER_HEADER buffer =
+ (PIMDPROXY_DEVIODRV_BUFFER_HEADER)MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
+ NormalPagePriority);
+
+ if (buffer == NULL)
+ {
+ KdPrint(("IRP=%p Failed getting direct I/O address.\n",
+ Irp));
+
+ DevIoDrvCompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
+
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ KdPrint(("IRP=%p Request to lock memory. Queuing server IRP.\n", Irp));
+
+ PIRP_QUEUE_ITEM memory_irp = (PIRP_QUEUE_ITEM)
+ ExAllocatePoolWithTag(NonPagedPool, sizeof IRP_QUEUE_ITEM, POOL_TAG);
+
+ if (memory_irp == NULL)
+ {
+ DevIoDrvCompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
+
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(memory_irp, sizeof(*memory_irp));
+
+ memory_irp->Irp = Irp;
+ memory_irp->MappedBuffer = buffer;
+
+ DevIoDrvQueueMemoryIrp(memory_irp, context, LowestAssumedIrql);
+
+ return STATUS_PENDING;
+}
+
+NTSTATUS
+DevIoDrvDispatchServerIORequest(PIRP Irp,
+ PKIRQL LowestAssumedIrql)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ KdPrint(("IRP=%p Server I/O request.\n", Irp));
+
+ if (io_stack->Parameters.DeviceIoControl.OutputBufferLength > 0 &&
+ io_stack->Parameters.DeviceIoControl.OutputBufferLength < IMDPROXY_HEADER_SIZE)
+ {
+ KdPrint(("IRP=%p Buffer too small: %u.\n",
+ Irp, io_stack->Parameters.DeviceIoControl.OutputBufferLength));
+
+ DevIoDrvCompleteIrp(Irp, STATUS_BUFFER_TOO_SMALL, 0);
+
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ PIRP_QUEUE_ITEM memory_irp;
+ PIMDPROXY_DEVIODRV_BUFFER_HEADER buffer;
+ ULONG buffer_size;
+
+ NTSTATUS status = DevIoDrvReserveMemoryIrp(Irp, &memory_irp, &buffer, &buffer_size, LowestAssumedIrql);
+
+ if (!NT_SUCCESS(status))
+ {
+ KdPrint(("IRP=%p Failed getting direct I/O address. %#x\n",
+ Irp, status));
+
+ DevIoDrvCompleteIrp(Irp, status, 0);
+
+ return status;
+ }
+
+ KdPrint(("IRP=%p I/O tag %#I64x, request code %#I64x flags %#I64x.\n",
+ Irp, buffer->io_tag, buffer->request_code, buffer->flags));
+
+ PIRP_QUEUE_ITEM client_item = NULL;
+
+ if (buffer->io_tag != 0)
+ {
+ client_item = DevIoDrvGetSentClientRequest(context, buffer->io_tag, LowestAssumedIrql);
+
+ if (client_item == NULL)
+ {
+ KdPrint(("IRP=%p Error finding client request with tag %#I64x.\n",
+ Irp, buffer->io_tag));
+
+ DevIoDrvCompleteIrp(Irp, STATUS_INVALID_PARAMETER, 0);
+
+ DevIoDrvQueueMemoryIrp(memory_irp, context, LowestAssumedIrql);
+
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ KdPrint(("IRP=%p Server request completing client IRP=%p.\n",
+ Irp, client_item->Irp));
+ }
+
+ PIMDPROXY_READ_RESP read_write_response = (PIMDPROXY_READ_RESP)(buffer + 1);
+
+ if (client_item == NULL && buffer->request_code == IMDPROXY_REQ_INFO)
+ {
+ KdPrint(("IRP=%p IMDPROXY_REQ_INFO.\n",
+ Irp));
+
+ PIMDPROXY_INFO_RESP response = (PIMDPROXY_INFO_RESP)(buffer + 1);
+ context->FileSize.QuadPart = response->file_size;
+ context->AlignmentRequirement = (ULONG)(response->req_alignment - 1);
+ context->ServiceFlags = response->flags;
+ }
+ else if (client_item != NULL &&
+ IoGetCurrentIrpStackLocation(client_item->Irp)->MajorFunction == IRP_MJ_READ &&
+ buffer->request_code == IMDPROXY_REQ_READ &&
+ IoGetCurrentIrpStackLocation(client_item->Irp)->Parameters.Read.Length >= read_write_response->length &&
+ buffer_size >= IMDPROXY_HEADER_SIZE + read_write_response->length)
+ {
+ KdPrint(("IRP=%p IMDPROXY_REQ_READ.\n", Irp));
+
+ PIMDPROXY_READ_RESP response = (PIMDPROXY_READ_RESP)(buffer + 1);
+
+ if (response->length > 0)
+ {
+ PVOID client_buffer = MmGetSystemAddressForMdlSafe(client_item->Irp->MdlAddress, NormalPagePriority);
+
+ if (client_buffer == NULL)
+ {
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_INSUFFICIENT_RESOURCES, 0, LowestAssumedIrql);
+ DevIoDrvCompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
+ DevIoDrvQueueMemoryIrp(memory_irp, context, LowestAssumedIrql);
+
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCopyMemory(client_buffer, ((PUCHAR)buffer) + IMDPROXY_HEADER_SIZE, (SIZE_T)response->length);
+ }
+
+ KIRQL irql;
+
+ KeRaiseIrql(APC_LEVEL, &irql);
+
+ KIRQL new_irql = APC_LEVEL;
+
+ if (response->errorno == 0)
+ {
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_SUCCESS, (ULONG_PTR)response->length, &new_irql);
+ }
+ else
+ {
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_IO_DEVICE_ERROR, (ULONG_PTR)response->length, &new_irql);
+ }
+
+ KeLowerIrql(irql);
+ }
+ else if (client_item != NULL &&
+ IoGetCurrentIrpStackLocation(client_item->Irp)->MajorFunction == IRP_MJ_WRITE &&
+ buffer->request_code == IMDPROXY_REQ_WRITE &&
+ IoGetCurrentIrpStackLocation(client_item->Irp)->Parameters.Write.Length >= read_write_response->length)
+ {
+ KdPrint(("IRP=%p IMDPROXY_REQ_WRITE.\n",
+ Irp));
+
+ PIMDPROXY_WRITE_RESP response = (PIMDPROXY_WRITE_RESP)(buffer + 1);
+
+ KIRQL irql;
+
+ KeRaiseIrql(APC_LEVEL, &irql);
+
+ KIRQL new_irql = APC_LEVEL;
+
+ if (response->errorno == 0)
+ {
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_SUCCESS, (ULONG_PTR)response->length, &new_irql);
+ }
+ else
+ {
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_IO_DEVICE_ERROR, (ULONG_PTR)response->length, &new_irql);
+ }
+
+ KeLowerIrql(irql);
+ }
+ else if (client_item == NULL && buffer->request_code == IMDPROXY_REQ_NULL)
+ {
+ // no response here, just wants next request
+
+ KdPrint(("IRP=%p IMDPROXY_REQ_NULL.\n",
+ Irp));
+ }
+ else
+ {
+ DbgPrint("IRP=%p Bad server request.\n", Irp);
+
+ KdBreakPoint();
+
+ if (client_item != NULL)
+ {
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_IO_DEVICE_ERROR, 0, LowestAssumedIrql);
+ }
+
+ DevIoDrvCompleteIrp(Irp, STATUS_INVALID_PARAMETER, 0);
+ DevIoDrvQueueMemoryIrp(memory_irp, context, LowestAssumedIrql);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PIRP_QUEUE_ITEM server_item = (PIRP_QUEUE_ITEM)ExAllocatePoolWithTag(NonPagedPool, sizeof IRP_QUEUE_ITEM, POOL_TAG);
+
+ if (server_item == NULL)
+ {
+ DevIoDrvCompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
+ DevIoDrvQueueMemoryIrp(memory_irp, context, LowestAssumedIrql);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(server_item, sizeof *server_item);
+
+ server_item->Irp = Irp;
+
+ KLOCK_QUEUE_HANDLE lock_handle;
+ DevIoDrvAcquireLock(&context->IrpListLock, &lock_handle, *LowestAssumedIrql);
+
+ PLIST_ENTRY entry = RemoveHeadList(&context->ClientReceivedIrpList);
+
+ if (entry == &context->ClientReceivedIrpList)
+ {
+ KdPrint(("IRP=%p No client request available. Queuing server IRP.\n", Irp));
+
+ KIRQL cancel_irql;
+
+ IoAcquireCancelSpinLock(&cancel_irql);
+
+ DevIoDrvQueueMemoryIrpUnsafe(memory_irp, context);
+
+ IoSetCancelRoutine(Irp, DevIoDrvServerIrpCancelRoutine);
+
+ IoMarkIrpPending(Irp);
+
+ InsertTailList(&context->ServerRequestIrpList, &server_item->ListEntry);
+
+ IoReleaseCancelSpinLock(cancel_irql);
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ return STATUS_PENDING;
+ }
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ server_item->MemoryIrp = memory_irp;
+ server_item->MappedBuffer = buffer;
+ server_item->MappedBufferSize = buffer_size;
+
+ KdPrint(("IRP=%p Client request found. Completing server request in-thread.\n",
+ Irp));
+
+ client_item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+
+ NTSTATUS client_status, server_status;
+ DevIoDrvSendClientRequestToServer(context, client_item, server_item, &client_status, &server_status, LowestAssumedIrql);
+
+ return server_status;
+}
+
+void
+DevIoDrvSendClientRequestToServer(POBJECT_CONTEXT File,
+ PIRP_QUEUE_ITEM ClientItem,
+ PIRP_QUEUE_ITEM ServerItem,
+ NTSTATUS *ClientStatus,
+ NTSTATUS *ServerStatus,
+ PKIRQL LowestAssumedIrql)
+{
+ if (ServerItem->MappedBuffer == NULL)
+ {
+ NTSTATUS status = DevIoDrvReserveMemoryIrp(ServerItem->Irp, &ServerItem->MemoryIrp, &ServerItem->MappedBuffer, &ServerItem->MappedBufferSize, LowestAssumedIrql);
+
+ if (!NT_SUCCESS(status))
+ {
+ KdPrint(("IRP=%p Failed getting direct I/O address. %#x\n",
+ ServerItem->Irp, status));
+
+ DevIoDrvCompleteIrpQueueItem(ClientItem, status, 0, LowestAssumedIrql);
+ DevIoDrvCompleteIrpQueueItem(ServerItem, status, 0, LowestAssumedIrql);
+
+ *ClientStatus = *ServerStatus = status;
+
+ return;
+ }
+ }
+
+ ServerItem->MappedBuffer->flags = 0;
+ ServerItem->MappedBuffer->io_tag = (ULONGLONG)(ULONG_PTR)&ClientItem->ListEntry;
+
+ KdPrint(("Sending client IRP=%p to server IRP=%p. I/O tag = %#I64x\n",
+ ClientItem->Irp, ServerItem->Irp, ServerItem->MappedBuffer->io_tag));
+
+ PIO_STACK_LOCATION io_stack_client = IoGetCurrentIrpStackLocation(ClientItem->Irp);
+
+ if (io_stack_client->MajorFunction == IRP_MJ_READ)
+ {
+ if (ServerItem->MappedBufferSize < IMDPROXY_HEADER_SIZE + io_stack_client->Parameters.Read.Length)
+ {
+ IoMarkIrpPending(ClientItem->Irp);
+ DevIoDrvInterlockedInsertHeadList(&File->ClientReceivedIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_BUFFER_TOO_SMALL, 0, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_BUFFER_TOO_SMALL;
+
+ return;
+ }
+
+ ServerItem->MappedBuffer->request_code = IMDPROXY_REQ_READ;
+
+ PIMDPROXY_READ_REQ request = (PIMDPROXY_READ_REQ)(ServerItem->MappedBuffer + 1);
+ request->request_code = IMDPROXY_REQ_READ;
+ request->offset = io_stack_client->Parameters.Read.ByteOffset.QuadPart;
+ request->length = io_stack_client->Parameters.Read.Length;
+
+ IoMarkIrpPending(ClientItem->Irp);
+
+ DevIoDrvInterlockedInsertTailList(&File->ClientSentIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_SUCCESS, IMDPROXY_HEADER_SIZE, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_SUCCESS;
+ }
+ else if (io_stack_client->MajorFunction == IRP_MJ_WRITE)
+ {
+ if (ServerItem->MappedBufferSize < IMDPROXY_HEADER_SIZE + io_stack_client->Parameters.Write.Length)
+ {
+ IoMarkIrpPending(ClientItem->Irp);
+ DevIoDrvInterlockedInsertHeadList(&File->ClientReceivedIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_BUFFER_TOO_SMALL, 0, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_BUFFER_TOO_SMALL;
+
+ return;
+ }
+
+ if (io_stack_client->Parameters.Write.Length > 0)
+ {
+ PVOID client_buffer = MmGetSystemAddressForMdlSafe(ClientItem->Irp->MdlAddress, NormalPagePriority);
+
+ if (client_buffer == NULL)
+ {
+ DevIoDrvCompleteIrpQueueItem(ClientItem, STATUS_INSUFFICIENT_RESOURCES, 0, LowestAssumedIrql);
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_INSUFFICIENT_RESOURCES, 0, LowestAssumedIrql);
+
+ *ClientStatus = *ServerStatus = STATUS_INSUFFICIENT_RESOURCES;
+
+ return;
+ }
+
+ RtlCopyMemory(((PUCHAR)ServerItem->MappedBuffer) + IMDPROXY_HEADER_SIZE, client_buffer, io_stack_client->Parameters.Write.Length);
+ }
+
+ ServerItem->MappedBuffer->request_code = IMDPROXY_REQ_WRITE;
+
+ PIMDPROXY_WRITE_REQ request = (PIMDPROXY_WRITE_REQ)(ServerItem->MappedBuffer + 1);
+ request->request_code = IMDPROXY_REQ_WRITE;
+ request->offset = io_stack_client->Parameters.Write.ByteOffset.QuadPart;
+ request->length = io_stack_client->Parameters.Write.Length;
+
+ IoMarkIrpPending(ClientItem->Irp);
+
+ DevIoDrvInterlockedInsertTailList(&File->ClientSentIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_SUCCESS, IMDPROXY_HEADER_SIZE + (ULONG_PTR)io_stack_client->Parameters.Write.Length, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_SUCCESS;
+ }
+ else if (io_stack_client->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
+ io_stack_client->Parameters.FileSystemControl.FsControlCode == FSCTL_SET_ZERO_DATA)
+ {
+ if (ServerItem->MappedBufferSize < IMDPROXY_HEADER_SIZE + sizeof DEVICE_DATA_SET_RANGE)
+ {
+ IoMarkIrpPending(ClientItem->Irp);
+ DevIoDrvInterlockedInsertHeadList(&File->ClientReceivedIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_BUFFER_TOO_SMALL, 0, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_BUFFER_TOO_SMALL;
+ return;
+ }
+
+ PFILE_ZERO_DATA_INFORMATION zero_info = (PFILE_ZERO_DATA_INFORMATION)ClientItem->Irp->AssociatedIrp.SystemBuffer;
+
+ ServerItem->MappedBuffer->request_code = IMDPROXY_REQ_ZERO;
+
+ PIMDPROXY_ZERO_REQ request = (PIMDPROXY_ZERO_REQ)(ServerItem->MappedBuffer + 1);
+ request->request_code = IMDPROXY_REQ_ZERO;
+ request->length = sizeof DEVICE_DATA_SET_RANGE;
+
+ PDEVICE_DATA_SET_RANGE range = (PDEVICE_DATA_SET_RANGE)((PUCHAR)ServerItem->MappedBuffer + IMDPROXY_HEADER_SIZE);
+ range->StartingOffset = zero_info->FileOffset.QuadPart;
+ range->LengthInBytes = zero_info->BeyondFinalZero.QuadPart - zero_info->FileOffset.QuadPart;
+
+ IoMarkIrpPending(ClientItem->Irp);
+
+ DevIoDrvInterlockedInsertTailList(&File->ClientSentIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_SUCCESS, IMDPROXY_HEADER_SIZE, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_SUCCESS;
+ }
+ else if (io_stack_client->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
+ io_stack_client->Parameters.FileSystemControl.FsControlCode == FSCTL_FILE_LEVEL_TRIM)
+ {
+ PFILE_LEVEL_TRIM trim_info = (PFILE_LEVEL_TRIM)ClientItem->Irp->AssociatedIrp.SystemBuffer;
+
+ if (ServerItem->MappedBufferSize < IMDPROXY_HEADER_SIZE + trim_info->NumRanges * sizeof DEVICE_DATA_SET_RANGE)
+ {
+ IoMarkIrpPending(ClientItem->Irp);
+ DevIoDrvInterlockedInsertHeadList(&File->ClientReceivedIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_BUFFER_TOO_SMALL, 0, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_BUFFER_TOO_SMALL;
+ return;
+ }
+
+ ServerItem->MappedBuffer->request_code = IMDPROXY_REQ_UNMAP;
+
+ PIMDPROXY_ZERO_REQ request = (PIMDPROXY_ZERO_REQ)(ServerItem->MappedBuffer + 1);
+ request->request_code = IMDPROXY_REQ_UNMAP;
+ request->length = trim_info->NumRanges * sizeof DEVICE_DATA_SET_RANGE;
+
+ PDEVICE_DATA_SET_RANGE range = (PDEVICE_DATA_SET_RANGE)((PUCHAR)ServerItem->MappedBuffer + IMDPROXY_HEADER_SIZE);
+
+ for (ULONG i = 0; i < trim_info->NumRanges; i++)
+ {
+ range[i].StartingOffset = trim_info->Ranges[i].Offset;
+ range[i].LengthInBytes = trim_info->Ranges[i].Length;
+ }
+
+ IoMarkIrpPending(ClientItem->Irp);
+
+ DevIoDrvInterlockedInsertTailList(&File->ClientSentIrpList, &ClientItem->ListEntry, &File->IrpListLock, LowestAssumedIrql);
+
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_SUCCESS, IMDPROXY_HEADER_SIZE, LowestAssumedIrql);
+
+ *ClientStatus = STATUS_PENDING;
+ *ServerStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ DevIoDrvCompleteIrpQueueItem(ClientItem, STATUS_INTERNAL_ERROR, 0, LowestAssumedIrql);
+ DevIoDrvCompleteIrpQueueItem(ServerItem, STATUS_INTERNAL_ERROR, 0, LowestAssumedIrql);
+
+ *ClientStatus = *ServerStatus = STATUS_INTERNAL_ERROR;
+ }
+}
+
+NTSTATUS
+DevIoDrvDispatchClientRequest(PIRP Irp,
+ PKIRQL LowestAssumedIrql)
+{
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ if (context->Server == NULL)
+ {
+ KdPrint(("DevIoDrv: IRP=%p Request to disconnected device.\n", Irp));
+
+ DevIoDrvCompleteIrp(Irp, STATUS_DEVICE_DOES_NOT_EXIST, 0);
+ return STATUS_DEVICE_DOES_NOT_EXIST;
+ }
+
+ PIRP_QUEUE_ITEM client_item = (PIRP_QUEUE_ITEM)ExAllocatePoolWithTag(NonPagedPool, sizeof IRP_QUEUE_ITEM, POOL_TAG);
+
+ if (client_item == NULL)
+ {
+ DevIoDrvCompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(client_item, sizeof *client_item);
+
+ client_item->Irp = Irp;
+
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ DevIoDrvAcquireLock(&context->IrpListLock, &lock_handle, *LowestAssumedIrql);
+
+ if (context->Server == NULL)
+ {
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ KdPrint(("DevIoDrv: IRP=%p Request to disconnected device.\n", Irp));
+
+ DevIoDrvCompleteIrpQueueItem(client_item, STATUS_DEVICE_DOES_NOT_EXIST, 0, LowestAssumedIrql);
+
+ return STATUS_DEVICE_DOES_NOT_EXIST;
+ }
+
+ KIRQL cancel_irql;
+
+ IoAcquireCancelSpinLock(&cancel_irql);
+
+ PLIST_ENTRY entry;
+ PIRP_QUEUE_ITEM server_item;
+
+ for (;;)
+ {
+ entry = RemoveHeadList(&context->ServerRequestIrpList);
+ server_item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+
+ if (entry != &context->ServerRequestIrpList)
+ {
+ if (server_item->Irp->Cancel)
+ {
+ continue;
+ }
+
+ IoSetCancelRoutine(server_item->Irp, NULL);
+ }
+
+ break;
+ }
+
+ IoReleaseCancelSpinLock(cancel_irql);
+
+ if (entry == &context->ServerRequestIrpList)
+ {
+ IoMarkIrpPending(Irp);
+
+ InsertTailList(&context->ClientReceivedIrpList, &client_item->ListEntry);
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ KdPrint(("IRP=%p FileObject=%p No server irp available. Queuing client request.\n",
+ Irp, io_stack->FileObject));
+
+ return STATUS_PENDING;
+ }
+
+ DevIoDrvReleaseLock(&lock_handle, LowestAssumedIrql);
+
+ KdPrint(("IRP=%p FileObject=%p Found pending server IRP=%p. Completing client request in-thread.\n",
+ Irp, io_stack->FileObject, server_item->Irp));
+
+ NTSTATUS client_status, server_status;
+ DevIoDrvSendClientRequestToServer(context, client_item, server_item, &client_status, &server_status, LowestAssumedIrql);
+
+ return client_status;
+}
+
+void
+DevIoDrvServerIrpCancelRoutine(PDEVICE_OBJECT, PIRP Irp)
+{
+ IoSetCancelRoutine(Irp, NULL);
+
+ IoReleaseCancelSpinLock(DISPATCH_LEVEL);
+
+ PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ POBJECT_CONTEXT context = (POBJECT_CONTEXT)io_stack->FileObject->FsContext2;
+
+ KdPrint(("IRP=%p FileObject=%p Cancel request.\n", Irp, io_stack->FileObject));
+
+ KLOCK_QUEUE_HANDLE lock_handle;
+
+ DevIoDrvAcquireLock(&context->IrpListLock, &lock_handle, DISPATCH_LEVEL);
+
+ PLIST_ENTRY irp_list = NULL;
+
+ if (io_stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DEVIODRV_EXCHANGE_IO)
+ {
+ irp_list = &context->ServerRequestIrpList;
+ }
+ else if (io_stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DEVIODRV_LOCK_MEMORY)
+ {
+ irp_list = &context->ServerMemoryIrpList;
+ }
+ else
+ {
+ RtlAssert("Unknown IoControlCode in cancel routine.", __FILE__, __LINE__,
+ "Unknown IoControlCode in cancel routine.");
+ }
+
+ PIRP_QUEUE_ITEM item = NULL;
+
+ for (PLIST_ENTRY entry = irp_list->Flink; entry != irp_list; entry = entry->Flink)
+ {
+ item = CONTAINING_RECORD(entry, IRP_QUEUE_ITEM, ListEntry);
+
+ if (item->Irp == Irp)
+ {
+ RemoveEntryList(entry);
+ ExFreePoolWithTag(item, POOL_TAG);
+ break;
+ }
+ }
+
+ KIRQL lowest_assumed_irql = DISPATCH_LEVEL;
+
+ DevIoDrvReleaseLock(&lock_handle, &lowest_assumed_irql);
+
+ KeLowerIrql(Irp->CancelIrql);
+
+ DevIoDrvCompleteIrp(Irp, STATUS_CANCELLED, 0);
+}
diff --git a/deviodrv/sources b/deviodrv/sources
new file mode 100644
index 0000000..6a498f1
--- /dev/null
+++ b/deviodrv/sources
@@ -0,0 +1,8 @@
+TARGETNAME=deviodrv
+TARGETPATH=.
+TARGETTYPE=DRIVER
+SOURCES=deviodrv.cpp dispatch.cpp filetable.cpp irpfwd.cpp deviodrv.rc
+MSC_WARNING_LEVEL=/W4 /WX /wd4100 /wd4201
+!IF "$(NTDEBUG)" != "ntsd"
+MSC_OPTIMIZATION=/Ox /GF
+!ENDIF
diff --git a/imdisk.inf b/imdisk.inf
index 14dbeab..68c0d50 100644
--- a/imdisk.inf
+++ b/imdisk.inf
@@ -1,7 +1,7 @@
[Version]
signature = "$Windows NT$"
Provider = "LTR Data"
-DriverVer=11/19/2018,6.0.6001.18000
+DriverVer=10/30/2021,2.1.0
[SourceDisksNames]
@@ -9,6 +9,7 @@ DriverVer=11/19/2018,6.0.6001.18000
[SourceDisksFiles.x86]
+deviodrv.sys = 1,deviodrv\i386
awealloc.sys = 1,awealloc\i386
imdisk.sys = 1,sys\i386
imdsksvc.exe = 1,svc\i386
@@ -20,6 +21,7 @@ uninstall_imdisk.cmd = 1
[SourceDisksFiles.ia64]
+deviodrv.sys = 1,deviodrv\ia64
awealloc.sys = 1,awealloc\ia64
imdisk.sys = 1,sys\ia64
imdsksvc.exe = 1,svc\ia64
@@ -31,6 +33,7 @@ uninstall_imdisk.cmd = 1
[SourceDisksFiles.amd64]
+deviodrv.sys = 1,deviodrv\amd64
awealloc.sys = 1,awealloc\amd64
imdisk.sys = 1,sys\amd64
imdsksvc.exe = 1,svc\amd64
@@ -42,6 +45,7 @@ uninstall_imdisk.cmd = 1
[SourceDisksFiles.arm]
+deviodrv.sys = 1,deviodrv\arm
awealloc.sys = 1,awealloc\arm
imdisk.sys = 1,sys\arm
imdsksvc.exe = 1,svc\arm
@@ -53,6 +57,7 @@ uninstall_imdisk.cmd = 1
[SourceDisksFiles.arm64]
+deviodrv.sys = 1,deviodrv\arm64
awealloc.sys = 1,awealloc\arm64
imdisk.sys = 1,sys\arm64
imdsksvc.exe = 1,svc\arm64
@@ -127,60 +132,70 @@ DelReg = ImDiskDelReg
[DefaultInstall.ntx86.Services]
+AddService = DevIoDrv, , DevIoDrv
AddService = AWEAlloc, , AWEAllocDrv
AddService = ImDisk, , ImDskDrv
AddService = ImDskSvc, , ImDskSvc
[DefaultUninstall.ntx86.Services]
+DelService = DevIoDrv
DelService = AWEAlloc
DelService = ImDisk
DelService = ImDskSvc
[DefaultInstall.ntarm.Services]
+AddService = DevIoDrv, , DevIoDrv
AddService = AWEAlloc, , AWEAllocDrv
AddService = ImDisk, , ImDskDrv
AddService = ImDskSvc, , ImDskSvc
[DefaultUninstall.ntarm.Services]
+DelService = DevIoDrv
DelService = AWEAlloc
DelService = ImDisk
DelService = ImDskSvc
[DefaultInstall.ntamd64.Services]
+AddService = DevIoDrv, , DevIoDrv
AddService = AWEAlloc, , AWEAllocDrv
AddService = ImDisk, , ImDskDrv
AddService = ImDskSvc, , ImDskSvc
[DefaultUninstall.ntamd64.Services]
+DelService = DevIoDrv
DelService = AWEAlloc
DelService = ImDisk
DelService = ImDskSvc
[DefaultInstall.ntarm64.Services]
+AddService = DevIoDrv, , DevIoDrv
AddService = AWEAlloc, , AWEAllocDrv
AddService = ImDisk, , ImDskDrv
AddService = ImDskSvc, , ImDskSvc
[DefaultUninstall.ntarm64.Services]
+DelService = DevIoDrv
DelService = AWEAlloc
DelService = ImDisk
DelService = ImDskSvc
[DefaultInstall.ntia64.Services]
+AddService = DevIoDrv, , DevIoDrv
AddService = AWEAlloc, , AWEAllocDrv
AddService = ImDisk, , ImDskDrv
AddService = ImDskSvc, , ImDskSvc
[DefaultUninstall.ntia64.Services]
+DelService = DevIoDrv
DelService = AWEAlloc
DelService = ImDisk
DelService = ImDskSvc
@@ -199,6 +214,7 @@ imdisk.cpl,cpl\i386\imdisk.cpl
[ImDiskSysFiles]
+deviodrv.sys
awealloc.sys
imdisk.sys
@@ -267,6 +283,15 @@ ErrorControl = 0
ServiceBinary = %12%\awealloc.sys
+[DevIoDrv]
+DisplayName = "DevIO Client Driver"
+Description = "Client driver for ImDisk devio proxy mode"
+ServiceType = 1
+StartType = 2
+ErrorControl = 0
+ServiceBinary = %12%\deviodrv.sys
+
+
[ImDskSvc]
DisplayName = "ImDisk Virtual Disk Driver Helper"
Description = "Helper service for ImDisk Virtual Disk Driver."
diff --git a/imdisk.props b/imdisk.props
index 99023f2..383a273 100644
--- a/imdisk.props
+++ b/imdisk.props
@@ -8,8 +8,8 @@
Default
- _UNICODE;UNICODE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_WCSTOK;NT4_COMPATIBLE;WIN32_LEAN_AND_MEAN;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);%(PreprocessorDefinitions)
- 4996;4201;4306;%(DisableSpecificWarnings)
+ _UNICODE;UNICODE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_WCSTOK;NT4_COMPATIBLE;INCLUDE_GPL_ORIGIN;WIN32_LEAN_AND_MEAN;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);%(PreprocessorDefinitions)
+ 4996;4201;4306;4127;28159;%(DisableSpecificWarnings)
false
Level4
true
diff --git a/inc/imdisk.h b/inc/imdisk.h
index 6b364a6..b0f6300 100644
--- a/inc/imdisk.h
+++ b/inc/imdisk.h
@@ -1,7 +1,7 @@
/*
ImDisk Virtual Disk Driver for Windows NT/2000/XP.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -108,16 +108,16 @@ OTHER DEALINGS IN THE SOFTWARE.
#define IMDISK_WINVER() ((IMDISK_WINVER_MAJOR() << 8) | \
IMDISK_WINVER_MINOR())
-#if defined(NT4_COMPATIBLE) && !defined(_WIN64)
+#if defined(NT4_COMPATIBLE) && defined(_M_IX86)
#define IMDISK_GTE_WIN2K() (IMDISK_WINVER_MAJOR() >= 0x05)
#else
#define IMDISK_GTE_WIN2K() TRUE
#endif
-#ifdef _WIN64
-#define IMDISK_GTE_WINXP() TRUE
-#else
+#ifdef _M_IX86
#define IMDISK_GTE_WINXP() (IMDISK_WINVER() >= 0x0501)
+#else
+#define IMDISK_GTE_WINXP() TRUE
#endif
#define IMDISK_GTE_SRV2003() (IMDISK_WINVER() >= 0x0502)
@@ -221,6 +221,9 @@ OTHER DEALINGS IN THE SOFTWARE.
#define IMDISK_FILE_TYPE_AWEALLOC 0x00001000
/// Direct parallel I/O to an image file, done in request thread
#define IMDISK_FILE_TYPE_PARALLEL_IO 0x00002000
+/// Buffered I/O to an image file. Disables FILE_NO_INTERMEDIATE_BUFFERING when
+/// opening image file.
+#define IMDISK_FILE_TYPE_BUFFERED_IO 0x00003000
/// Extracts the IMDISK_FILE_TYPE_xxx from flags
#define IMDISK_FILE_TYPE(x) ((ULONG)(x) & 0x0000F000)
@@ -1535,6 +1538,10 @@ extern "C" {
CDECL
ImDiskAllocPrintF(LPCWSTR lpMessage, ...);
+ IMDISK_API LPSTR
+ CDECL
+ ImDiskAllocPrintFA(LPCSTR lpMessage, ...);
+
IMDISK_API int
WINAPI
ImDiskConsoleMessageA(
@@ -1551,6 +1558,10 @@ extern "C" {
LPCWSTR lpCaption,
UINT uType);
+ IMDISK_API BOOL
+ WINAPI
+ ImDiskIsProcessElevated();
+
#ifdef CORE_BUILD
#ifdef CharToOemA
diff --git a/inc/imdiskver.h b/inc/imdiskver.h
index 0c12331..6c1a73c 100644
--- a/inc/imdiskver.h
+++ b/inc/imdiskver.h
@@ -1,6 +1,9 @@
-#define IMDISK_RC_VERSION_STR "2.0.10"
-#define IMDISK_MAJOR_VERSION 2
-#define IMDISK_MINOR_VERSION 0
-#define IMDISK_MINOR_LOW_VERSION 10
+#define IMDISK_MAJOR_VERSION 2
+#define IMDISK_MINOR_VERSION 1
+#define IMDISK_MINOR_LOW_VERSION 1
-#define IMDISK_RC_VERSION_FLD IMDISK_MAJOR_VERSION,IMDISK_MINOR_VERSION,IMDISK_MINOR_LOW_VERSION
+#define STR_EXPAND(tok) #tok
+#define STR(tok) STR_EXPAND(tok)
+
+#define IMDISK_RC_VERSION_FLD IMDISK_MAJOR_VERSION,IMDISK_MINOR_VERSION,IMDISK_MINOR_LOW_VERSION
+#define IMDISK_RC_VERSION_STR STR(IMDISK_MAJOR_VERSION) "." STR(IMDISK_MINOR_VERSION) "." STR(IMDISK_MINOR_LOW_VERSION)
diff --git a/inc/imdproxy.h b/inc/imdproxy.h
index 7121111..167d85e 100644
--- a/inc/imdproxy.h
+++ b/inc/imdproxy.h
@@ -34,12 +34,18 @@ typedef uint32_t ULONG;
typedef int64_t LONGLONG;
typedef uint64_t ULONGLONG;
typedef u_short WCHAR;
+typedef u_char UCHAR;
#endif
#define IMDPROXY_SVC L"ImDskSvc"
#define IMDPROXY_SVC_PIPE_DOSDEV_NAME L"\\\\.\\PIPE\\" IMDPROXY_SVC
#define IMDPROXY_SVC_PIPE_NATIVE_NAME L"\\Device\\NamedPipe\\" IMDPROXY_SVC
+#define DEVIODRV_DEVICE_NAME L"DevIoDrv"
+#define DEVIODRV_DEVICE_DOSDEV_NAME L"\\\\.\\" DEVIODRV_DEVICE_NAME
+#define DEVIODRV_DEVICE_NATIVE_NAME L"\\Device\\" DEVIODRV_DEVICE_NAME
+#define DEVIODRV_SYMLINK_NATIVE_NAME L"\\DosDevices\\" DEVIODRV_DEVICE_NAME
+
#define IMDPROXY_FLAG_RO 0x01 // Read-only
#define IMDPROXY_FLAG_SUPPORTS_UNMAP 0x02 // Unmap/TRIM ranges
#define IMDPROXY_FLAG_SUPPORTS_ZERO 0x04 // Zero-fill ranges
@@ -60,6 +66,11 @@ typedef enum _IMDPROXY_REQ
IMDPROXY_REQ_SHARED
} IMDPROXY_REQ, *PIMDPROXY_REQ;
+typedef struct _IMDPROXY_CLOSE_REQ
+{
+ ULONGLONG request_code;
+} IMDPROXY_CLOSE_REQ, *PIMDPROXY_CLOSE_REQ;
+
typedef struct _IMDPROXY_CONNECT_REQ
{
ULONGLONG request_code;
@@ -189,4 +200,21 @@ typedef enum _IMDPROXY_SHARED_RESP_CODE
// shared memory.
#define IMDPROXY_HEADER_SIZE 4096
+// For use with deviodrv driver, where requests and responses are tagged
+// with an id for asynchronous operations.
+typedef struct _IMDPROXY_DEVIODRV_BUFFER_HEADER
+{
+ ULONGLONG request_code; // Request code to forward to response header.
+ ULONGLONG io_tag; // Tag to forward to response header.
+ ULONGLONG flags; // Reserved. Currently not used.
+} IMDPROXY_DEVIODRV_BUFFER_HEADER, *PIMDPROXY_DEVIODRV_BUFFER_HEADER;
+
+#if defined(CTL_CODE) && !defined(IOCTL_DEVIODRV_EXCHANGE_IO)
+#ifndef FILE_DEVICE_IMDISK
+#define FILE_DEVICE_IMDISK 0x8372
+#endif
+#define IOCTL_DEVIODRV_EXCHANGE_IO ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x8D0, METHOD_OUT_DIRECT, FILE_READ_ACCESS | FILE_WRITE_ACCESS))
+#define IOCTL_DEVIODRV_LOCK_MEMORY ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x8D1, METHOD_OUT_DIRECT, FILE_READ_ACCESS | FILE_WRITE_ACCESS))
+#endif
+
#endif // _INC_IMDPROXY_
diff --git a/inc/ntkmapi.h b/inc/ntkmapi.h
index 763af24..12ca53a 100644
--- a/inc/ntkmapi.h
+++ b/inc/ntkmapi.h
@@ -10,7 +10,7 @@
// Ensures that we build a pre Win 2000 compatible x86 sys file
// (without ExFreePoolWithTag()). // Olof Lagerkvist
//
-#ifndef _WIN64
+#if defined(_M_IX86)
#ifdef ExFreePool
#undef ExFreePool
#endif
diff --git a/inc/ntumapi.h b/inc/ntumapi.h
index 2bc9722..98552db 100644
--- a/inc/ntumapi.h
+++ b/inc/ntumapi.h
@@ -6,6 +6,7 @@
extern "C" {
#endif
+#if !defined(_NTDEF_) && !defined(_NTSECAPI_)
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
@@ -13,6 +14,7 @@ typedef struct _UNICODE_STRING {
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
+#endif
#define UNICODE_NULL ((WCHAR)0)
typedef LONG NTSTATUS;
@@ -623,6 +625,24 @@ typedef struct _REPARSE_INDEX_KEY {
#pragma pack()
+NTSYSAPI
+ULONG
+__cdecl
+DbgPrint(
+ IN PCSTR Format,
+ ...
+);
+
+NTSYSAPI
+ULONG
+__cdecl
+DbgPrintEx(
+ IN ULONG ComponentId,
+ IN ULONG Level,
+ IN PCSTR Format,
+ ...
+);
+
NTSYSAPI
BOOLEAN
NTAPI
diff --git a/readme.txt b/readme.txt
index c290455..e67f8b6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -23,7 +23,7 @@
this product under NT 3.51 you have to manually add registry entries needed
by driver and service or use resource kit tools to add necessary settings.
- Copyright (c) 2005-2016 Olof Lagerkvist
+ Copyright (c) 2005-2018 Olof Lagerkvist
http://www.ltr-data.se olof@ltr-data.se
Permission is hereby granted, free of charge, to any person
diff --git a/svc/imdsksvc.cpp b/svc/imdsksvc.cpp
index cf3f87a..0e8eee6 100644
--- a/svc/imdsksvc.cpp
+++ b/svc/imdsksvc.cpp
@@ -5,7 +5,7 @@ This service redirects I/O requests sent to the ImDisk Virtual Disk Driver
to another computer through a serial communication interface or by opening
a TCP/IP connection.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -40,9 +40,11 @@ OTHER DEALINGS IN THE SOFTWARE.
#include "..\inc\imdisk.h"
#include "..\inc\imdproxy.h"
+#include "..\inc\ntumapi.h"
#include "..\inc\wio.hpp"
#include "..\inc\wmem.hpp"
+#pragma comment(lib, "ntdll.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "ws2_32.lib")
@@ -57,33 +59,9 @@ HANDLE ImDiskSvcStopEvent = NULL;
#if defined(DEBUG) || defined(_DEBUG)
-#define KdPrint(x) DbgPrintF x
+#define KdPrint(x) DbgPrint x
#define KdPrintLastError(x) DbgPrintLastError x
-BOOL
-DbgPrintF(LPCSTR Message, ...)
-{
- va_list param_list;
- LPSTR lpBuf = NULL;
-
- va_start(param_list, Message);
-
- if (!FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK |
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_STRING, Message, 0, 0,
- (LPSTR)&lpBuf, 0, ¶m_list))
- return FALSE;
-
- OutputDebugStringA(lpBuf);
-
- DWORD dw;
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), lpBuf, (DWORD)strlen(lpBuf), &dw, NULL);
-
- LocalFree(lpBuf);
-
- return TRUE;
-}
-
void
DbgPrintLastError(LPCSTR Prefix)
{
@@ -95,7 +73,7 @@ DbgPrintLastError(LPCSTR Prefix)
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, (LPSTR)&MsgBuf, 0, NULL);
- DbgPrintF("ImDskSvc: %1: %2%n", Prefix, MsgBuf);
+ DbgPrint("ImDskSvc: %s: %s\n", Prefix, MsgBuf);
LocalFree(MsgBuf);
}
@@ -116,7 +94,7 @@ class ImDiskSvcServerSession
{
IMDPROXY_CONNECT_REQ ConnectReq;
- KdPrint(("ImDskSvc: Thread created.%n"));
+ KdPrint(("ImDskSvc: Thread created.\n"));
if (Overlapped.BufRecv(hPipe, &ConnectReq.request_code,
sizeof ConnectReq.request_code) !=
@@ -148,9 +126,9 @@ class ImDiskSvcServerSession
return 0;
}
- if ((ConnectReq.length == 0) | (ConnectReq.length > 520))
+ if ((ConnectReq.length == 0) || (ConnectReq.length > 520))
{
- KdPrint(("ImDskSvc: Bad connection string length received (%1!u!).%n",
+ KdPrint(("ImDskSvc: Bad connection string length received (%u).\n",
ConnectReq.length));
delete this;
@@ -200,7 +178,7 @@ class ImDiskSvcServerSession
{
LPWSTR FileName = wcstok(ConnectionString, L": ");
- KdPrint(("ImDskSvc: Connecting to '%1!ws!'.%n", FileName));
+ KdPrint(("ImDskSvc: Connecting to '%ws'.\n", FileName));
hTarget = CreateFile(FileName,
GENERIC_READ | GENERIC_WRITE,
@@ -231,7 +209,7 @@ class ImDiskSvcServerSession
if (DCBAndTimeouts[0] == L' ')
++DCBAndTimeouts;
- KdPrint(("ImDskSvc: Configuring '%1!ws!'.%n", DCBAndTimeouts));
+ KdPrint(("ImDskSvc: Configuring '%ws'.\n", DCBAndTimeouts));
GetCommState(hTarget, &dcb);
GetCommTimeouts(hTarget, &timeouts);
@@ -240,7 +218,7 @@ class ImDiskSvcServerSession
SetCommTimeouts(hTarget, &timeouts);
}
- KdPrint(("ImDskSvc: Connected to '%1!ws!' and configured.%n",
+ KdPrint(("ImDskSvc: Connected to '%ws' and configured.\n",
FileName));
break;
@@ -255,7 +233,7 @@ class ImDiskSvcServerSession
if (PortName == NULL)
PortName = L"9000";
- KdPrint(("ImDskSvc: Connecting to '%1!ws!:%2!ws!'.%n",
+ KdPrint(("ImDskSvc: Connecting to '%ws:%ws'.\n",
ServerName, PortName));
hTarget = (HANDLE)ConnectTCP(ServerName, PortName);
@@ -276,14 +254,14 @@ class ImDiskSvcServerSession
setsockopt((SOCKET)hTarget, IPPROTO_TCP, TCP_NODELAY, (LPCSTR)&b,
sizeof b);
- KdPrint(("ImDskSvc: Connected to '%1!ws!:%2!ws!' and configured.%n",
+ KdPrint(("ImDskSvc: Connected to '%ws:%ws' and configured.\n",
ServerName, PortName));
break;
}
default:
- KdPrint(("ImDskSvc: Unsupported connection type (%1!#x!).%n",
+ KdPrint(("ImDskSvc: Unsupported connection type (%#x).\n",
IMDISK_PROXY_TYPE(ConnectReq.flags)));
connect_resp.error_code = (ULONGLONG)-1;
@@ -406,7 +384,7 @@ class ImDiskSvcServerSession
// we should shut down this connection.
Overlapped.BufRecv(hPipe, &dw, sizeof dw);
- KdPrint(("ImDskSvc: Cleaning up.%n"));
+ KdPrint(("ImDskSvc: Cleaning up.\n"));
CloseHandle(hTarget);
@@ -452,7 +430,7 @@ class ImDiskSvcServerSession
} ThreadFunction;
ThreadFunction.Member = &ImDiskSvcServerSession::Thread;
- KdPrint(("ImDskSvc: Creating thread.%n"));
+ KdPrint(("ImDskSvc: Creating thread.\n"));
UINT id = 0;
HANDLE hThread = (HANDLE)
@@ -501,8 +479,8 @@ class ImDiskSvcServerSession
return false;
return
- (hPipe != NULL) &
- (hPipe != INVALID_HANDLE_VALUE) &
+ (hPipe != NULL) &&
+ (hPipe != INVALID_HANDLE_VALUE) &&
(Overlapped.hEvent != NULL);
}
};
@@ -545,6 +523,7 @@ ImDiskSvcStart(DWORD, LPWSTR *)
ImDiskSvcStatusHandle = RegisterServiceCtrlHandler(IMDPROXY_SVC,
ImDiskSvcCtrlHandler);
+
if (ImDiskSvcStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
KdPrintLastError(("RegisterServiceCtrlHandler() failed"));
@@ -586,6 +565,8 @@ ImDiskSvcStart(DWORD, LPWSTR *)
SetServiceStatus(ImDiskSvcStatusHandle, &ImDiskSvcStatus);
}
+#ifdef _DEBUG
+
extern "C"
int
CALLBACK
@@ -595,7 +576,62 @@ wWinMain(HINSTANCE,
LPWSTR,
int)
{
- KdPrint(("ImDskSvc: Starting up process.%n"));
+ KdPrint(("ImDskSvc: Starting up process.\n"));
+
+ WSADATA wsadata;
+ WSAStartup(0x0101, &wsadata);
+
+ ImDiskSvcStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (ImDiskSvcStopEvent == NULL)
+ {
+ KdPrintLastError(("CreateEvent() failed"));
+ return 0;
+ }
+
+ for (;;)
+ {
+ if (WaitForSingleObject(ImDiskSvcStopEvent, 0) != WAIT_TIMEOUT)
+ {
+ ImDiskSvcStatus.dwWin32ExitCode = NO_ERROR;
+ break;
+ }
+
+#pragma warning(suppress: 28197)
+ ImDiskSvcServerSession* ServerSession = new ImDiskSvcServerSession;
+ if (!ServerSession->IsOk())
+ {
+ delete ServerSession;
+ KdPrintLastError(("Pipe initialization failed"));
+ break;
+ }
+
+ if (!ServerSession->Connect())
+ {
+ if (ImDiskSvcStatus.dwWin32ExitCode != NO_ERROR)
+ {
+ KdPrintLastError(("Pipe connect failed"));
+ }
+ break;
+ }
+ }
+
+ SetEvent(ImDiskSvcStopEvent);
+
+ return 1;
+}
+
+#else
+
+extern "C"
+int
+CALLBACK
+#pragma warning(suppress: 28251)
+wWinMain(HINSTANCE,
+ HINSTANCE,
+ LPWSTR,
+ int)
+{
+ KdPrint(("ImDskSvc: Starting up process.\n"));
WSADATA wsadata;
WSAStartup(0x0101, &wsadata);
@@ -631,6 +667,8 @@ wWinMain(HINSTANCE,
return 1;
}
+#endif
+
#if !defined(_DEBUG) && !defined(DEBUG) && _MSC_PLATFORM_TOOLSET < 140
// We have our own EXE entry to be less dependent on
diff --git a/svc/imdsksvc.rc b/svc/imdsksvc.rc
index 72d9f5e..c053430 100644
--- a/svc/imdsksvc.rc
+++ b/svc/imdsksvc.rc
@@ -28,7 +28,7 @@ BEGIN
VALUE "FileDescription", "ImDisk Virtual Disk Driver helper service\0"
VALUE "FileVersion", IMDISK_RC_VERSION_STR ".24\0"
VALUE "InternalName", "imdsksvc\0"
- VALUE "LegalCopyright", "Copyright © 2005-2018 Olof Lagerkvist.\0"
+ VALUE "LegalCopyright", "Copyright © 2005-2021 Olof Lagerkvist.\0"
VALUE "OriginalFilename", "imdsksvc.exe\0"
VALUE "ProductName", "imdisk\0"
VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".24\0"
diff --git a/svc/svc.inf b/svc/svc.inf
new file mode 100644
index 0000000..bf07140
--- /dev/null
+++ b/svc/svc.inf
@@ -0,0 +1,54 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = svc.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk Virtual Disk Driver Helper Service"
+
+
+[SourceDisksFiles.x86]
+imdsksvc.exe = 1, i386
+
+[SourceDisksFiles.ia64]
+imdsksvc.exe = 1, ia64
+
+[SourceDisksFiles.amd64]
+imdsksvc.exe = 1, amd64
+
+[SourceDisksFiles.arm]
+imdsksvc.exe = 1, arm
+
+[SourceDisksFiles.arm64]
+imdsksvc.exe = 1, arm64
+
+[DestinationDirs]
+ImDskSvcExeFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ImDskSvcExeFiles
+
+
+[ImDskSvcExeFiles]
+imdsksvc.exe
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDskSvc, , ImDskSvc
+
+
+[ImDskSvc]
+DisplayName = "ImDisk Virtual Disk Driver Helper Service"
+StartType = 2
+ServiceType = 16
+ErrorControl = 0
+ServiceBinary = %11%\imdsksvc.exe
diff --git a/sys/commonio.cpp b/sys/commonio.cpp
index 7821349..1a661d8 100644
--- a/sys/commonio.cpp
+++ b/sys/commonio.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/sys/createdev.cpp b/sys/createdev.cpp
index 2a3e949..078614a 100644
--- a/sys/createdev.cpp
+++ b/sys/createdev.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -43,7 +43,7 @@ Copyright (C) The Regents of the University of California.
#include "imdsksys.h"
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
// For floppy devices. Based on Virtual Floppy Driver, VFD, by Ken Kato.
#define SECTOR_SIZE_FDD 512
@@ -115,7 +115,7 @@ const DISK_GEOMETRY media_table[] = {
#define SET_MEDIA_TYPE(geometry, media_index) \
(geometry.MediaType = media_table[media_index].MediaType)
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
VOID
ImDiskFindFreeDeviceNumber(PDRIVER_OBJECT DriverObject,
@@ -211,7 +211,7 @@ ImDiskReadFormattedGeometry(IN OUT PIMDISK_CREATE_DATA CreateData,
if (CreateData->DiskGeometry.BytesPerSector == 0)
CreateData->DiskGeometry.BytesPerSector = BPB->BytesPerSector;
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
if (((IMDISK_DEVICE_TYPE(CreateData->Flags) == IMDISK_DEVICE_TYPE_FD) |
(IMDISK_DEVICE_TYPE(CreateData->Flags) == 0)) &
@@ -291,7 +291,7 @@ ImDiskReadFormattedGeometry(IN OUT PIMDISK_CREATE_DATA CreateData,
break;
}
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
KdPrint
(("ImDisk: Values after BPB geometry detection:\n"
@@ -475,17 +475,23 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
// Auto-select type if not specified.
if (IMDISK_TYPE(CreateData->Flags) == 0)
+ {
if (CreateData->FileNameLength == 0)
+ {
CreateData->Flags |= IMDISK_TYPE_VM;
+ }
else
+ {
CreateData->Flags |= IMDISK_TYPE_FILE;
+ }
+ }
// Blank filenames only supported for memory disks where size is specified.
if ((CreateData->FileNameLength == 0) &&
- !(((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_VM) &
- (CreateData->DiskGeometry.Cylinders.QuadPart > 65536)) |
- ((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_FILE) &
- (IMDISK_FILE_TYPE(CreateData->Flags) == IMDISK_FILE_TYPE_AWEALLOC) &
+ !(((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_VM) &&
+ (CreateData->DiskGeometry.Cylinders.QuadPart > 65536)) ||
+ ((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_FILE) &&
+ (IMDISK_FILE_TYPE(CreateData->Flags) == IMDISK_FILE_TYPE_AWEALLOC) &&
(CreateData->DiskGeometry.Cylinders.QuadPart > 65536))))
{
KdPrint(("ImDisk: Blank filenames only supported for memory disks where "
@@ -529,12 +535,6 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
KdPrint(("ImDisk: Free device number %i.\n", CreateData->DeviceNumber));
}
- /* for (CreateData->DeviceNumber = 0; */
- /* CreateData->DeviceNumber < MaxDevices; */
- /* CreateData->DeviceNumber++) */
- /* if ((~DeviceList) & (1ULL << CreateData->DeviceNumber)) */
- /* break; */
-
if (CreateData->DeviceNumber >= MaxDevices)
{
ImDiskLogError((DriverObject,
@@ -556,7 +556,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
if (IMDISK_BYTE_SWAP(CreateData->Flags) &&
(IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_FILE) &&
- (IMDISK_FILE_TYPE(CreateData->Flags) == IMDISK_FILE_TYPE_PARALLEL_IO))
+ (IMDISK_FILE_TYPE(CreateData->Flags) != IMDISK_FILE_TYPE_BUFFERED_IO))
{
ImDiskLogError((DriverObject,
0,
@@ -584,8 +584,8 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
// If a file is to be opened or created, allocate name buffer and open that
// file...
- if ((CreateData->FileNameLength > 0) |
- ((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_FILE) &
+ if ((CreateData->FileNameLength > 0) ||
+ ((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_FILE) &&
(IMDISK_FILE_TYPE(CreateData->Flags) == IMDISK_FILE_TYPE_AWEALLOC)))
{
IO_STATUS_BLOCK io_status;
@@ -715,9 +715,9 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
NULL,
NULL);
}
- else if ((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_PROXY) &
+ else if ((IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_PROXY) &&
((IMDISK_PROXY_TYPE(CreateData->Flags) ==
- IMDISK_PROXY_TYPE_TCP) |
+ IMDISK_PROXY_TYPE_TCP) ||
(IMDISK_PROXY_TYPE(CreateData->Flags) ==
IMDISK_PROXY_TYPE_COMM)))
{
@@ -772,9 +772,11 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
}
create_options = FILE_NON_DIRECTORY_FILE |
- FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT;
+ if (IMDISK_FILE_TYPE(CreateData->Flags) != IMDISK_FILE_TYPE_BUFFERED_IO)
+ create_options |= FILE_NO_INTERMEDIATE_BUFFERING;
+
if (IMDISK_SPARSE_FILE(CreateData->Flags))
{
create_options |= FILE_OPEN_FOR_BACKUP_INTENT;
@@ -810,7 +812,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
// call will fail because OBJ_FORCE_ACCESS_CHECK is not supported. If so,
// STATUS_INVALID_PARAMETER is returned and we go on without any access
// checks in that case.
-#ifndef _WIN64
+#ifdef _M_IX86
if (status == STATUS_INVALID_PARAMETER)
{
InitializeObjectAttributes(&object_attributes,
@@ -1180,6 +1182,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
&max_size,
MEM_COMMIT,
PAGE_READWRITE);
+
if (!NT_SUCCESS(status))
{
ZwClose(file_handle);
@@ -1245,15 +1248,17 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
}
if (CreateData->DiskGeometry.Cylinders.QuadPart == 0)
+ {
CreateData->DiskGeometry.Cylinders.QuadPart =
- disk_size.QuadPart -
- CreateData->ImageOffset.QuadPart;
+ disk_size.QuadPart -
+ CreateData->ImageOffset.QuadPart;
+ }
alignment_requirement = file_alignment.AlignmentRequirement;
}
- if ((CreateData->DiskGeometry.TracksPerCylinder == 0) |
- (CreateData->DiskGeometry.SectorsPerTrack == 0) |
+ if ((CreateData->DiskGeometry.TracksPerCylinder == 0) ||
+ (CreateData->DiskGeometry.SectorsPerTrack == 0) ||
(CreateData->DiskGeometry.BytesPerSector == 0))
{
SIZE_T free_size = 0;
@@ -1362,8 +1367,8 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
if (CreateData->DiskGeometry.Cylinders.QuadPart == 0)
CreateData->DiskGeometry.Cylinders.QuadPart = proxy_info.file_size;
- if ((CreateData->DiskGeometry.TracksPerCylinder == 0) |
- (CreateData->DiskGeometry.SectorsPerTrack == 0) |
+ if ((CreateData->DiskGeometry.TracksPerCylinder == 0) ||
+ (CreateData->DiskGeometry.SectorsPerTrack == 0) ||
(CreateData->DiskGeometry.BytesPerSector == 0))
{
WPoolMem fat_vbr(sizeof(FAT_VBR));
@@ -1399,11 +1404,12 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
sizeof(FAT_VBR),
&CreateData->ImageOffset);
- if (!NT_SUCCESS(status))
+ if (NT_SUCCESS(status))
+ {
+ ImDiskReadFormattedGeometry(CreateData, &fat_vbr->BPB);
+ }
+ else
{
- ImDiskCloseProxy(&proxy);
- ZwClose(file_handle);
-
ImDiskLogError((DriverObject,
0,
0,
@@ -1420,14 +1426,10 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
KdPrint(("ImDisk: Error reading first sector (%#x).\n",
status));
-
- return status;
}
-
- ImDiskReadFormattedGeometry(CreateData, &fat_vbr->BPB);
}
- if ((proxy_info.req_alignment - 1 > FILE_512_BYTE_ALIGNMENT) |
+ if ((proxy_info.req_alignment - 1 > FILE_512_BYTE_ALIGNMENT) ||
(CreateData->DiskGeometry.Cylinders.QuadPart == 0))
{
ImDiskCloseProxy(&proxy);
@@ -1526,6 +1528,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
&max_size,
MEM_COMMIT,
PAGE_READWRITE);
+
if (!NT_SUCCESS(status))
{
KdPrint
@@ -1554,7 +1557,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
KdPrint(("ImDisk: Done with file/memory checks.\n"));
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
// If no device-type specified and size matches common floppy sizes,
// auto-select FILE_DEVICE_DISK with FILE_FLOPPY_DISKETTE and
@@ -1587,12 +1590,12 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
KdPrint(("ImDisk: Done with device type selection for floppy sizes.\n"));
-#else // INCLUDE_VFD_ORIGIN
+#else // INCLUDE_GPL_ORIGIN
if (IMDISK_DEVICE_TYPE(CreateData->Flags) == 0)
CreateData->Flags |= IMDISK_DEVICE_TYPE_HD;
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
// If some parts of the DISK_GEOMETRY structure are zero, auto-fill with
// typical values for this type of disk.
@@ -1636,7 +1639,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
{
LONGLONG calccyl = CreateData->DiskGeometry.Cylinders.QuadPart;
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
if ((IMDISK_DEVICE_TYPE(CreateData->Flags) == IMDISK_DEVICE_TYPE_FD) &
(CreateData->DiskGeometry.BytesPerSector == 0) &
@@ -1709,7 +1712,7 @@ ImDiskCreateDevice(__in PDRIVER_OBJECT DriverObject,
// defined floppy geometries above.
CreateData->DiskGeometry.Cylinders.QuadPart = calccyl;
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
if (CreateData->DiskGeometry.BytesPerSector == 0)
CreateData->DiskGeometry.BytesPerSector = SECTOR_SIZE_HDD;
diff --git a/sys/devthrd.cpp b/sys/devthrd.cpp
index 8290ae9..524967c 100644
--- a/sys/devthrd.cpp
+++ b/sys/devthrd.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -55,6 +55,8 @@ ImDiskDeviceThreadRead(IN PIRP Irp,
LARGE_INTEGER offset;
KLOCK_QUEUE_HANDLE lock_handle;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
if (system_buffer == NULL)
{
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -136,11 +138,6 @@ ImDiskDeviceThreadRead(IN PIRP Irp,
DeviceExtension->device_number,
Irp->IoStatus.Status));
- // If indicating that proxy connection died we can do
- // nothing else but remove this device.
- // if (Irp->IoStatus.Status == STATUS_CONNECTION_RESET)
- ImDiskRemoveVirtualDisk(DeviceObject);
-
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
Irp->IoStatus.Information = 0;
}
@@ -202,6 +199,8 @@ ImDiskDeviceThreadWrite(IN PIRP Irp,
BOOLEAN set_zero_data = FALSE;
KLOCK_QUEUE_HANDLE lock_handle;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
if (system_buffer == NULL)
{
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -335,11 +334,6 @@ ImDiskDeviceThreadWrite(IN PIRP Irp,
DeviceExtension->device_number,
Irp->IoStatus.Status));
- // If indicating that proxy connection died we can do
- // nothing else but remove this device.
- if (Irp->IoStatus.Status == STATUS_CONNECTION_RESET)
- ImDiskRemoveVirtualDisk(DeviceObject);
-
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
Irp->IoStatus.Information = 0;
}
@@ -511,6 +505,8 @@ ImDiskDeviceThreadDeviceControl(IN PIRP Irp,
{
PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
+ UNREFERENCED_PARAMETER(DeviceObject);
+
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_DISK_CHECK_VERIFY:
@@ -561,11 +557,6 @@ ImDiskDeviceThreadDeviceControl(IN PIRP Irp,
KdPrint(("ImDisk: Verify failed on device %i.\n",
DeviceExtension->device_number));
- // If indicating that proxy connection died we can do
- // nothing else but remove this device.
- if (Irp->IoStatus.Status == STATUS_CONNECTION_RESET)
- ImDiskRemoveVirtualDisk(DeviceObject);
-
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
Irp->IoStatus.Information = 0;
break;
@@ -695,7 +686,7 @@ ImDiskDeviceThreadDeviceControl(IN PIRP Irp,
break;
}
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
case IOCTL_DISK_FORMAT_TRACKS:
case IOCTL_DISK_FORMAT_TRACKS_EX:
@@ -705,11 +696,6 @@ ImDiskDeviceThreadDeviceControl(IN PIRP Irp,
if (!NT_SUCCESS(status))
{
- // If indicating that proxy connection died we can do
- // nothing else but remove this device.
- if (status == STATUS_CONNECTION_RESET)
- ImDiskRemoveVirtualDisk(DeviceObject);
-
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
Irp->IoStatus.Information = 0;
break;
@@ -720,7 +706,7 @@ ImDiskDeviceThreadDeviceControl(IN PIRP Irp,
break;
}
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES:
{
@@ -1276,6 +1262,23 @@ ImDiskDeviceThread(IN PVOID Context)
Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
+ // If indicating that proxy connection died we can do
+ // nothing else but remove this device.
+ switch (Irp->IoStatus.Status)
+ {
+ case STATUS_CONNECTION_RESET:
+ case STATUS_DEVICE_REMOVED:
+ case STATUS_DEVICE_DOES_NOT_EXIST:
+ case STATUS_PIPE_BROKEN:
+ case STATUS_PIPE_DISCONNECTED:
+ case STATUS_PORT_DISCONNECTED:
+ case STATUS_REMOTE_DISCONNECT:
+ ImDiskRemoveVirtualDisk(device_object);
+ Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
+ Irp->IoStatus.Information = 0;
+
+ }
+
IoCompleteRequest(Irp,
NT_SUCCESS(Irp->IoStatus.Status) ?
IO_DISK_INCREMENT : IO_NO_INCREMENT);
diff --git a/sys/floppy.cpp b/sys/floppy.cpp
index d9d0144..5ad256f 100644
--- a/sys/floppy.cpp
+++ b/sys/floppy.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -45,7 +45,7 @@ Copyright (C) The Regents of the University of California.
#pragma code_seg("PAGE")
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
//
// Format tracks
@@ -153,4 +153,4 @@ ImDiskFloppyFormat(IN PDEVICE_EXTENSION Extension,
return status;
}
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
diff --git a/sys/imdisk.cpp b/sys/imdisk.cpp
index 1acb8ce..b8c0c9b 100644
--- a/sys/imdisk.cpp
+++ b/sys/imdisk.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -108,7 +108,12 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
OBJECT_ATTRIBUTES object_attributes;
ULONG n;
- KdBreakPoint();
+#if DBG
+ if (!KD_DEBUGGER_NOT_PRESENT)
+ {
+ KdBreakPoint();
+ }
+#endif
KeInitializeSpinLock(&DeviceListLock);
@@ -1020,7 +1025,7 @@ ImDiskCreateDriveLetter(IN WCHAR DriveLetter,
IN ULONG DeviceNumber)
{
WCHAR sym_link_global_wchar[] = L"\\DosDevices\\Global\\ :";
-#ifndef _WIN64
+#ifdef _M_IX86
WCHAR sym_link_wchar[] = L"\\DosDevices\\ :";
#endif
UNICODE_STRING sym_link;
@@ -1049,7 +1054,7 @@ ImDiskCreateDriveLetter(IN WCHAR DriveLetter,
device_name_buffer[MAXIMUM_FILENAME_LENGTH - 1] = 0;
RtlInitUnicodeString(&device_name, device_name_buffer);
-#ifndef _WIN64
+#ifdef _M_IX86
sym_link_wchar[12] = DriveLetter;
KdPrint(("ImDisk: Creating symlink '%ws' -> '%ws'.\n",
diff --git a/sys/imdisk.rc b/sys/imdisk.rc
index 337d7e9..e4c1c48 100644
--- a/sys/imdisk.rc
+++ b/sys/imdisk.rc
@@ -10,8 +10,8 @@
//
VS_VERSION_INFO VERSIONINFO
-FILEVERSION IMDISK_RC_VERSION_FLD,64
-PRODUCTVERSION IMDISK_RC_VERSION_FLD,64
+FILEVERSION IMDISK_RC_VERSION_FLD,65
+PRODUCTVERSION IMDISK_RC_VERSION_FLD,65
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifndef DEBUG
FILEFLAGS 0
@@ -28,12 +28,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Olof Lagerkvist\0"
VALUE "FileDescription", "ImDisk Virtual Disk Driver\0"
- VALUE "FileVersion", IMDISK_RC_VERSION_STR ".64\0"
+ VALUE "FileVersion", IMDISK_RC_VERSION_STR ".65\0"
VALUE "InternalName", "imdisk\0"
- VALUE "LegalCopyright", "Copyright © 2005-2018 Olof Lagerkvist etc.\0"
+ VALUE "LegalCopyright", "Copyright © 2005-2021 Olof Lagerkvist etc.\0"
VALUE "OriginalFilename", "imdisk.sys\0"
VALUE "ProductName", "imdisk\0"
- VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".64\0"
+ VALUE "ProductVersion", IMDISK_RC_VERSION_STR ".65\0"
END
END
BLOCK "VarFileInfo"
diff --git a/sys/imdsksys.h b/sys/imdsksys.h
index 090df53..a24e052 100644
--- a/sys/imdsksys.h
+++ b/sys/imdsksys.h
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -174,7 +174,8 @@ typedef struct _DEVICE_EXTENSION
BOOLEAN vm_disk; // TRUE if this device is a virtual memory disk
BOOLEAN awealloc_disk; // TRUE if this device is a physical memory disk
// through AWEAlloc driver
- BOOLEAN use_proxy; // TRUE if this device uses proxy device for I/O
+ BOOLEAN use_proxy; // TRUE if this device uses proxy service through
+ // shared memory, TCP/IP, serial port etc for I/O
BOOLEAN proxy_unmap; // TRUE if proxy supports UNMAP operations
BOOLEAN proxy_zero; // TRUE if proxy supports ZERO operations
BOOLEAN image_modified; // TRUE if this device has been written to
@@ -346,13 +347,13 @@ ImDiskReadWriteLowerDevice(PIRP Irp, PDEVICE_EXTENSION DeviceExtension);
NTSTATUS
ImDiskDeviceControlLowerDevice(PIRP Irp, PDEVICE_EXTENSION DeviceExtension);
-#ifdef INCLUDE_VFD_ORIGIN
+#ifdef INCLUDE_GPL_ORIGIN
NTSTATUS
ImDiskFloppyFormat(IN PDEVICE_EXTENSION Extension,
IN PIRP Irp);
-#endif // INCLUDE_VFD_ORIGIN
+#endif // INCLUDE_GPL_ORIGIN
#ifdef _AMD64_
diff --git a/sys/iodisp.cpp b/sys/iodisp.cpp
index 922eabd..fb1c246 100644
--- a/sys/iodisp.cpp
+++ b/sys/iodisp.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -81,7 +81,7 @@ ImDiskDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,
KdPrint(("ImDisk: Attempt to open device %i when shut down.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
@@ -126,7 +126,7 @@ ImDiskDispatchReadWrite(IN PDEVICE_OBJECT DeviceObject,
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
+ return STATUS_INVALID_PARAMETER;
}
device_extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -150,7 +150,7 @@ ImDiskDispatchReadWrite(IN PDEVICE_OBJECT DeviceObject,
KdPrint(("ImDisk: Read/write attempt on device %i while removing.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
@@ -348,7 +348,7 @@ ImDiskDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
KdPrint(("ImDisk: IOCTL attempt on device %i that is being removed.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
@@ -811,6 +811,7 @@ ImDiskDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
case IOCTL_DISK_EJECT_MEDIA:
case IOCTL_STORAGE_EJECT_MEDIA:
+ {
KdPrint(("ImDisk: IOCTL_DISK/STORAGE_EJECT_MEDIA for device %i.\n",
device_extension->device_number));
@@ -826,6 +827,7 @@ ImDiskDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
}
break;
+ }
case IOCTL_IMDISK_QUERY_DRIVER:
{
@@ -1911,10 +1913,10 @@ ImDiskDispatchFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
if (KeReadStateEvent(&device_extension->terminate_thread) != 0)
{
- KdPrint(("ImDisk: flush dispatch on device %i that is being removed.\n",
+ KdPrint(("ImDisk: Flush dispatch on device %i that is being removed.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
@@ -1998,7 +2000,7 @@ ImDiskDispatchQueryInformation(IN PDEVICE_OBJECT DeviceObject,
KdPrint(("ImDisk: QueryInformation dispatch on device %i that is being removed.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
@@ -2121,7 +2123,7 @@ ImDiskDispatchSetInformation(IN PDEVICE_OBJECT DeviceObject,
KdPrint(("ImDisk: SetInformation dispatch on device %i that is being removed.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
@@ -2222,7 +2224,7 @@ ImDiskDispatchPnP(IN PDEVICE_OBJECT DeviceObject,
KdPrint(("ImDisk: PnP dispatch on device %i that is being removed.\n",
device_extension->device_number));
- status = STATUS_DEVICE_DOES_NOT_EXIST;
+ status = STATUS_DEVICE_REMOVED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
diff --git a/sys/lowerdev.cpp b/sys/lowerdev.cpp
index 10f5092..ebf2581 100644
--- a/sys/lowerdev.cpp
+++ b/sys/lowerdev.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -93,6 +93,28 @@ ImDiskReadWriteLowerDeviceCompletion(PDEVICE_OBJECT DeviceObject,
{
KdPrint(("ImDiskReadWriteLowerDeviceCompletion: Parallel I/O failed with status %#x\n",
Irp->IoStatus.Status));
+
+ // If indicating that proxy connection died we can do
+ // nothing else but remove this device.
+ switch (item->OriginalIrp->IoStatus.Status)
+ {
+ case STATUS_CONNECTION_RESET:
+ case STATUS_DEVICE_REMOVED:
+ case STATUS_DEVICE_DOES_NOT_EXIST:
+ case STATUS_PIPE_BROKEN:
+ case STATUS_PIPE_DISCONNECTED:
+ case STATUS_PORT_DISCONNECTED:
+ case STATUS_REMOTE_DISCONNECT:
+ ImDiskRemoveVirtualDisk(DeviceObject);
+ item->OriginalIrp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
+ item->OriginalIrp->IoStatus.Information = 0;
+
+ }
+
+ if (item->AllocatedBuffer != NULL)
+ {
+ ExFreePoolWithTag(item->AllocatedBuffer, POOL_TAG);
+ }
}
else
{
diff --git a/sys/proxy.cpp b/sys/proxy.cpp
index fdda6b4..54acc39 100644
--- a/sys/proxy.cpp
+++ b/sys/proxy.cpp
@@ -5,7 +5,7 @@ drives from disk image files, in virtual memory or by redirecting I/O
requests somewhere else, possibly to another machine, through a
co-operating user-mode service, ImDskSvc.
-Copyright (C) 2005-2018 Olof Lagerkvist.
+Copyright (C) 2005-2021 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -435,11 +435,10 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
base_name.Length = ConnectionStringLength;
base_name.MaximumLength = ConnectionStringLength;
event_name.MaximumLength = ConnectionStringLength + 20;
- event_name.Buffer =
- (PWCHAR)ExAllocatePoolWithTag(PagedPool,
- event_name.MaximumLength,
- POOL_TAG);
- if (event_name.Buffer == NULL)
+
+ WPoolMem event_name_buffer(event_name.MaximumLength);
+
+ if (!event_name_buffer)
{
status = STATUS_INSUFFICIENT_RESOURCES;
@@ -448,6 +447,8 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
return IoStatusBlock->Status;
}
+ event_name.Buffer = event_name_buffer;
+
InitializeObjectAttributes(&object_attributes,
&event_name,
OBJ_CASE_INSENSITIVE,
@@ -464,7 +465,6 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
if (!NT_SUCCESS(status))
{
Proxy->request_event_handle = NULL;
- ExFreePoolWithTag(event_name.Buffer, POOL_TAG);
IoStatusBlock->Status = status;
IoStatusBlock->Information = 0;
@@ -481,7 +481,6 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
if (!NT_SUCCESS(status))
{
Proxy->request_event = NULL;
- ExFreePoolWithTag(event_name.Buffer, POOL_TAG);
IoStatusBlock->Status = status;
IoStatusBlock->Information = 0;
@@ -498,7 +497,6 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
if (!NT_SUCCESS(status))
{
Proxy->response_event_handle = NULL;
- ExFreePoolWithTag(event_name.Buffer, POOL_TAG);
IoStatusBlock->Status = status;
IoStatusBlock->Information = 0;
@@ -515,7 +513,6 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
if (!NT_SUCCESS(status))
{
Proxy->response_event = NULL;
- ExFreePoolWithTag(event_name.Buffer, POOL_TAG);
IoStatusBlock->Status = status;
IoStatusBlock->Information = 0;
@@ -596,6 +593,7 @@ ImDiskConnectProxy(IN OUT PPROXY_CONNECTION Proxy,
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
+ status = irp->IoStatus.Status;
}
if (!NT_SUCCESS(status))
diff --git a/sys/sources b/sys/sources
index 34cabe5..3a48619 100644
--- a/sys/sources
+++ b/sys/sources
@@ -2,11 +2,11 @@ TARGETNAME=imdisk
TARGETPATH=.
TARGETTYPE=DRIVER
-MSC_WARNING_LEVEL=/W4 /WX /wd4201 /wd4204 /wd4221
+MSC_WARNING_LEVEL=/W4 /WX /wd4201 /wd4204 /wd4221 /wd4482
!IF "$(NTDEBUG)" != "ntsd"
MSC_OPTIMIZATION=/Ox /GF
!ENDIF
-C_DEFINES=$(C_DEFINES) /DINCLUDE_VFD_ORIGIN
+C_DEFINES=$(C_DEFINES) /DINCLUDE_GPL_ORIGIN
!IF "$(_BUILDARCH)" == "x86"
LINKER_FLAGS=llmath.lib
diff --git a/sys/sources.props b/sys/sources.props
index 5319c42..76922a0 100644
--- a/sys/sources.props
+++ b/sys/sources.props
@@ -7,7 +7,7 @@
imdisk.c imdisk.rc
/W4 /WX /wd4201 /wd4204 /wd4221
/Ox /GF
- $(C_DEFINES) /DINCLUDE_VFD_ORIGIN
+ $(C_DEFINES) /DINCLUDE_GPL_ORIGIN
diff --git a/sys/sys.inf b/sys/sys.inf
new file mode 100644
index 0000000..33e6bb8
--- /dev/null
+++ b/sys/sys.inf
@@ -0,0 +1,55 @@
+
+; DUMMY.INF
+; Dummy inf file.
+
+[Version]
+signature = "$Windows NT$"
+Class = SCSIAdapter
+ClassGUID = {4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider = "LTR Data"
+DriverVer = 10/26/2021,2.1.0.00070
+CatalogFile = sys.cat
+
+
+[SourceDisksNames]
+1 = "ImDisk Virtual Disk Driver"
+
+
+[SourceDisksFiles.x86]
+imdisk.sys = 1, i386
+
+[SourceDisksFiles.ia64]
+imdisk.sys = 1, ia64
+
+[SourceDisksFiles.amd64]
+imdisk.sys = 1, amd64
+
+[SourceDisksFiles.arm]
+imdisk.sys = 1, arm
+
+[SourceDisksFiles.arm64]
+imdisk.sys = 1, arm64
+
+[DestinationDirs]
+ImDiskSysFiles = 12
+
+
+[DefaultInstall.ntx86]
+CopyFiles = ImDiskSysFiles
+
+
+[ImDiskSysFiles]
+imdisk.sys
+
+
+[DefaultInstall.ntx86.Services]
+AddService = ImDisk, , ImDiskDrv
+
+
+[ImDiskDrv]
+DisplayName = "ImDisk Virtual Disk Driver"
+StartType = 2
+ServiceType = 1
+ErrorControl = 0
+ServiceBinary = %12%\ImDisk.sys
+
diff --git a/sys/sys.props b/sys/sys.props
index 73bc6ee..13ad07c 100644
--- a/sys/sys.props
+++ b/sys/sys.props
@@ -1,8 +1,14 @@
-
+
-
+
+
+ DriverEntry
+
+
+
+
-
+
\ No newline at end of file
diff --git a/sys/sys.vcxproj b/sys/sys.vcxproj
index 5041910..b39d53a 100644
--- a/sys/sys.vcxproj
+++ b/sys/sys.vcxproj
@@ -305,8 +305,8 @@
-
+
@@ -360,76 +360,100 @@
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
- http://timestamp.globalsign.com/scripts/timstamp.dll
+
+
@@ -490,6 +514,7 @@
+
@@ -536,12 +561,12 @@
-
+