473,799 Members | 2,997 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A little C# -> VB.Net conversion help?

I have some C# code that is supposed to wrap the defrag APIs and I am trying
to convert it to VB.Net (2003). But, I keep having problems.

The C# code is relatively short, so I'll post it here.....

--------
//
// a set of simple C# wrappers over the NT Defragmenter APIs
//

//
// Refrences

//
// http://www.sysinternals.com/ntw2k/info/defrag.shtml
//
// msdn how-to
// ms-help://MS.MSDNQTR.2004 JUL.1033/fileio/base/defragmenting_f iles.htm
//
http://msdn.microsoft.com/library/de...ting_files.asp
//
// FSCTL_GET_VOLUM E_BITMAP
//
http://msdn.microsoft.com/library/de...ume_bitmap.asp
//
// interesting structures...
// FSCTL_MOVE_FILE
// FSCTL_GET_RETRI EVAL_POINTERS
// RETRIEVAL_POINT ERS_BUFFER
// FSCTL_GET_RETRI EVAL_POINTERS
//
// DeviceIoControl
//
http://msdn.microsoft.com/library/de...eiocontrol.asp
//

using System;
using System.Diagnost ics;
using System.Collecti ons;
using System.Runtime. InteropServices ;

namespace defraglib
{
public class IOWrapper
{

//
// CreateFile constants
//
const uint FILE_SHARE_READ = 0x00000001;
const uint FILE_SHARE_WRIT E = 0x00000002;
const uint FILE_SHARE_DELE TE = 0x00000004;
const uint OPEN_EXISTING = 3;

const uint GENERIC_READ = (0x80000000);
const uint GENERIC_WRITE = (0x40000000);

const uint FILE_FLAG_NO_BU FFERING = 0x20000000;
const uint FILE_READ_ATTRI BUTES = (0x0080);
const uint FILE_WRITE_ATTR IBUTES = 0x0100;
const uint ERROR_INSUFFICI ENT_BUFFER = 122;

[DllImport("kern el32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess ,
uint dwShareMode,
IntPtr lpSecurityAttri butes,
uint dwCreationDispo sition,
uint dwFlagsAndAttri butes,
IntPtr hTemplateFile);

[DllImport("kern el32.dll", SetLastError = true)]
static extern int CloseHandle(Int Ptr hObject);

[DllImport("kern el32.dll", SetLastError = true)]
static extern bool DeviceIoControl (
IntPtr hDevice,
uint dwIoControlCode ,
IntPtr lpInBuffer,
uint nInBufferSize,
[Out] IntPtr lpOutBuffer,
uint nOutBufferSize,
ref uint lpBytesReturned ,
IntPtr lpOverlapped);

static private IntPtr OpenVolume(stri ng DeviceName)
{
IntPtr hDevice;
hDevice = CreateFile(
@"\\.\" + DeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRIT E,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hDevice == -1)
{
throw new Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
return hDevice;
}

static private IntPtr OpenFile(string path)
{
IntPtr hFile;
hFile = CreateFile(
path,
FILE_READ_ATTRI BUTES | FILE_WRITE_ATTR IBUTES,
FILE_SHARE_READ | FILE_SHARE_WRIT E,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hFile == -1)
{
throw new Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
return hFile;
}
/// <summary>
/// Get cluster usage for a device
/// </summary>
/// <param name="DeviceNam e">use "c:"</param>
/// <returns>a bitarray for each cluster</returns>
static public BitArray GetVolumeMap(st ring DeviceName)
{
IntPtr pAlloc = IntPtr.Zero;
IntPtr hDevice = IntPtr.Zero;

try
{
hDevice = OpenVolume(Devi ceName);

Int64 i64 = 0;

GCHandle handle = GCHandle.Alloc( i64, GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();

// alloc off more than enough for my machine
// 64 megs == 67108864 bytes == 536870912 bits == cluster
count
// NTFS 4k clusters == 2147483648 k of storage == 2097152
megs == 2048 gig disk storage
uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

uint size = 0;
pAlloc = Marshal.AllocHG lobal((int)q);
IntPtr pDest = pAlloc;

bool fResult = DeviceIoControl (
hDevice,
FSConstants.FSC TL_GET_VOLUME_B ITMAP,
p,
(uint)Marshal.S izeOf(i64),
pDest,
q,
ref size,
IntPtr.Zero);

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
handle.Free();

/*
object returned was...
typedef struct
{
LARGE_INTEGER StartingLcn;
LARGE_INTEGER BitmapSize;
BYTE Buffer[1];
} VOLUME_BITMAP_B UFFER, *PVOLUME_BITMAP _BUFFER;
*/
Int64 StartingLcn = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Debug.Assert(St artingLcn == 0);

pDest = (IntPtr)((Int64 )pDest + 8);
Int64 BitmapSize = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Int32 byteSize = (int)(BitmapSiz e / 8);
byteSize++; // round up - even with no remainder

IntPtr BitmapBegin = (IntPtr)((Int64 )pDest + 8);

byte[] byteArr = new byte[byteSize];

Marshal.Copy(Bi tmapBegin, byteArr, 0, (Int32)byteSize );

BitArray retVal = new BitArray(byteAr r);
retVal.Length = (int)BitmapSize ; // truncate to exact
cluster count
return retVal;
}
finally
{
CloseHandle(hDe vice);
hDevice = IntPtr.Zero;

Marshal.FreeHGl obal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

/// <summary>
/// returns a 2*number of extents array -
/// the vcn and the lcn as pairs
/// </summary>
/// <param name="path">fil e to get the map for ex:
"c:\windows\exp lorer.exe" </param>
/// <returns>An array of [virtual cluster, physical
cluster]</returns>
static public Array GetFileMap(stri ng path)
{
IntPtr hFile = IntPtr.Zero;
IntPtr pAlloc = IntPtr.Zero;

try
{
hFile = OpenFile(path);

Int64 i64 = 0;

GCHandle handle = GCHandle.Alloc( i64, GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();

uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

uint size = 0;
pAlloc = Marshal.AllocHG lobal((int)q);
IntPtr pDest = pAlloc;
bool fResult = DeviceIoControl (
hFile,
FSConstants.FSC TL_GET_RETRIEVA L_POINTERS,
p,
(uint)Marshal.S izeOf(i64),
pDest,
q,
ref size,
IntPtr.Zero);

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}

handle.Free();

/*
returned back one of...
typedef struct RETRIEVAL_POINT ERS_BUFFER {
DWORD ExtentCount;
LARGE_INTEGER StartingVcn;
struct {
LARGE_INTEGER NextVcn;
LARGE_INTEGER Lcn;
} Extents[1];
} RETRIEVAL_POINT ERS_BUFFER, *PRETRIEVAL_POI NTERS_BUFFER;
*/

Int32 ExtentCount = (Int32)Marshal. PtrToStructure( pDest,
typeof(Int32));

pDest = (IntPtr)((Int64 )pDest + 4);

Int64 StartingVcn = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Debug.Assert(St artingVcn == 0);

pDest = (IntPtr)((Int64 )pDest + 8);

// now pDest points at an array of pairs of Int64s.

Array retVal = Array.CreateIns tance(typeof(In t64), new
int[2] { ExtentCount, 2 });

for (int i = 0; i < ExtentCount; i++)
{
for (int j = 0; j < 2; j++)
{
Int64 v = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));
retVal.SetValue (v, new int[2] { i, j });
pDest = (IntPtr)((Int64 )pDest + 8);
}
}

return retVal;
}
finally
{
CloseHandle(hFi le);
hFile = IntPtr.Zero;

Marshal.FreeHGl obal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

/// <summary>
/// input structure for use in MoveFile
/// </summary>
private struct MoveFileData
{
public IntPtr hFile;
public Int64 StartingVCN;
public Int64 StartingLCN;
public Int32 ClusterCount;
}

/// <summary>
/// move a virtual cluster for a file to a logical cluster on disk,
repeat for count clusters
/// </summary>
/// <param name="deviceNam e">device to move on"c:"</param>
/// <param name="path">fil e to muck with
"c:\windows\exp lorer.exe"</param>
/// <param name="VCN">clus ter number in file to move</param>
/// <param name="LCN">clus ter on disk to move to</param>
/// <param name="count">fo r how many clusters</param>
static public void MoveFile(string deviceName, string path, Int64
VCN, Int64 LCN, Int32 count)
{
IntPtr hVol = IntPtr.Zero;
IntPtr hFile = IntPtr.Zero;
try
{
hVol = OpenVolume(devi ceName);

hFile = OpenFile(path);
MoveFileData mfd = new MoveFileData();
mfd.hFile = hFile;
mfd.StartingVCN = VCN;
mfd.StartingLCN = LCN;
mfd.ClusterCoun t = count;

GCHandle handle = GCHandle.Alloc( mfd, GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();
uint bufSize = (uint)Marshal.S izeOf(mfd);
uint size = 0;

bool fResult = DeviceIoControl (
hVol,
FSConstants.FSC TL_MOVE_FILE,
p,
bufSize,
IntPtr.Zero, // no output data from this FSCTL
0,
ref size,
IntPtr.Zero);

handle.Free();

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
}
finally
{
CloseHandle(hVo l);
CloseHandle(hFi le);
}
}
}
/// <summary>
/// constants lifted from winioctl.h from platform sdk
/// </summary>
internal class FSConstants
{
const uint FILE_DEVICE_FIL E_SYSTEM = 0x00000009;

const uint METHOD_NEITHER = 3;
const uint METHOD_BUFFERED = 0;

const uint FILE_ANY_ACCESS = 0;
const uint FILE_SPECIAL_AC CESS = FILE_ANY_ACCESS ;

public static uint FSCTL_GET_VOLUM E_BITMAP =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 27, METHOD_NEITHER, FILE_ANY_ACCESS );
public static uint FSCTL_GET_RETRI EVAL_POINTERS =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 28, METHOD_NEITHER, FILE_ANY_ACCESS );
public static uint FSCTL_MOVE_FILE =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 29, METHOD_BUFFERED , FILE_SPECIAL_AC CESS);

static uint CTL_CODE(uint DeviceType, uint Function, uint Method,
uint Access)
{
return ((DeviceType) << 16) | ((Access) << 14) | ((Function) <<
2) | (Method);
}
}

}

-----

I'd be very grateful for any help with this conversion that you could offer.

Thanks!


Nov 16 '05 #1
5 1316
"Jim Hubbard" <re***@groups.p lease> schrieb:
I have some C# code that is supposed to wrap the defrag APIs and I am
trying
to convert it to VB.Net (2003). But, I keep having problems.


Converting code between .NET programming languages
<URL:http://dotnet.mvps.org/dotnet/faqs/?id=languagecon verters&lang=en >

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
Nov 16 '05 #2
Thanks for the links.

I tried all of the free converters, and all of the failed.

There were 2 here I had not seen before. The best of the free converters is
at http://authors.aspalliance.com/aldot...translate.aspx .

Although it also failed to convert the code, it is more verbose in the
reasons why.

"Herfried K. Wagner [MVP]" <hi************ ***@gmx.at> wrote in message
news:OT******** ******@TK2MSFTN GP10.phx.gbl...
"Jim Hubbard" <re***@groups.p lease> schrieb:
I have some C# code that is supposed to wrap the defrag APIs and I am
trying
to convert it to VB.Net (2003). But, I keep having problems.


Converting code between .NET programming languages
<URL:http://dotnet.mvps.org/dotnet/faqs/?id=languagecon verters&lang=en >

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>

Nov 16 '05 #3
Jim Hubbard wrote:
I have some C# code that is supposed to wrap the defrag APIs and I am trying
to convert it to VB.Net (2003). But, I keep having problems.

The C# code is relatively short, so I'll post it here.....
I wouldn't call that 'short' ;)
I'd be very grateful for any help with this conversion that you could offer.


It would be great if you could point out the problem area's. Converting
C# to VB.NET is easy, and you should use one of the on-line conversion
sites for that. It can be that these sites/tools choke on small
constructs, (as you use win32 code, it might be the case) so you then
should convert these small constructs by hand. If that gives problems,
post THOSE constructs so people here can help you with these.

Another tip: don't bother converting, as it will not gain you anything
(it will only waste your time). Why don't you put this code into a
library and use that one in VB.NET?

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Nov 16 '05 #4
Our Instant VB converter yields the following:
(feel free to download our Demo Edition at www.instantvb.com - it's the only
C# to VB converter that is fully supported)

Imports System
Imports System.Diagnost ics
Imports System.Collecti ons
Imports System.Runtime. InteropServices

Namespace defraglib
Public Class IOWrapper

'
' CreateFile constants
'
Private Const FILE_SHARE_READ As System.UInt32 = &H00000001
Private Const FILE_SHARE_WRIT E As System.UInt32 = &H00000002
Private Const FILE_SHARE_DELE TE As System.UInt32 = &H00000004
Private Const OPEN_EXISTING As System.UInt32 = 3

Private Const GENERIC_READ As System.UInt32 = (&H80000000)
Private Const GENERIC_WRITE As System.UInt32 = (&H40000000)

Private Const FILE_FLAG_NO_BU FFERING As System.UInt32 = &H20000000
Private Const FILE_READ_ATTRI BUTES As System.UInt32 = (&H0080)
Private Const FILE_WRITE_ATTR IBUTES As System.UInt32 = &H0100
Private Const ERROR_INSUFFICI ENT_BUFFER As System.UInt32 = 122

<DllImport("ker nel32.dll", SetLastError := True)> _
Shared Function CreateFile(ByVa l lpFileName As String, ByVal
dwDesiredAccess As System.UInt32, ByVal dwShareMode As System.UInt32, ByVal
lpSecurityAttri butes As IntPtr, ByVal dwCreationDispo sition As System.UInt32,
ByVal dwFlagsAndAttri butes As System.UInt32, ByVal hTemplateFile As IntPtr)
As IntPtr
End Function

<DllImport("ker nel32.dll", SetLastError := True)> _
Shared Function CloseHandle(ByV al hObject As IntPtr) As Integer
End Function

<DllImport("ker nel32.dll", SetLastError := True)> _
Shared Function DeviceIoControl (ByVal hDevice As IntPtr, ByVal
dwIoControlCode As System.UInt32, ByVal lpInBuffer As IntPtr, ByVal
nInBufferSize As System.UInt32, <Out> ByVal lpOutBuffer As IntPtr, ByVal
nOutBufferSize As System.UInt32, ByRef lpBytesReturned As System.UInt32,
ByVal lpOverlapped As IntPtr) As Boolean
End Function

Shared Private Function OpenVolume(ByVa l DeviceName As String) As IntPtr
Dim hDevice As IntPtr
hDevice = CreateFile("\\. \" + DeviceName, GENERIC_READ Or GENERIC_WRITE,
FILE_SHARE_WRIT E, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)
If CInt(hDevice) = -1 Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
Return hDevice
End Function

Shared Private Function OpenFile(ByVal path As String) As IntPtr
Dim hFile As IntPtr
hFile = CreateFile(path , FILE_READ_ATTRI BUTES Or FILE_WRITE_ATTR IBUTES,
FILE_SHARE_READ Or FILE_SHARE_WRIT E, IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero)
If CInt(hFile) = -1 Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
Return hFile
End Function
''' <summary>
''' Get cluster usage for a device
''' </summary>
''' <param name="DeviceNam e">use "c:"</param>
''' <returns>a bitarray for each cluster</returns>
Shared Public Function GetVolumeMap(By Val DeviceName As String) As BitArray
Dim pAlloc As IntPtr = IntPtr.Zero
Dim hDevice As IntPtr = IntPtr.Zero

Try
hDevice = OpenVolume(Devi ceName)

Dim i64 As Int64 = 0

Dim handle As GCHandle = GCHandle.Alloc( i64, GCHandleType.Pi nned)
Dim p As IntPtr = handle.AddrOfPi nnedObject()

' alloc off more than enough for my machine
' 64 megs == 67108864 bytes == 536870912 bits == cluster count
' NTFS 4k clusters == 2147483648 k of storage == 2097152 megs == 2048
gig disk storage
Dim q As System.UInt32 = 1024 * 1024 * 64 ' 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

Dim size As System.UInt32
pAlloc = Marshal.AllocHG lobal(CInt(q))
Dim pDest As IntPtr = pAlloc

Dim fResult As Boolean = DeviceIoControl (hDevice,
FSConstants.FSC TL_GET_VOLUME_B ITMAP, p, CUInt(Marshal.S izeOf(i64)), pDest, q,
size, IntPtr.Zero)

If (Not fResult) Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
handle.Free()

'
'object returned was...
'typedef struct
'{
'LARGE_INTEGER StartingLcn;
'LARGE_INTEGER BitmapSize;
'BYTE Buffer[1];
'} VOLUME_BITMAP_B UFFER, *PVOLUME_BITMAP _BUFFER;
'
Dim StartingLcn As Int64 = CLng(Marshal.Pt rToStructure(pD est,
GetType(Int64)) )

Debug.Assert(St artingLcn = 0)

pDest = CType(CLng(pDes t) + 8, IntPtr)
Dim BitmapSize As Int64 = CLng(Marshal.Pt rToStructure(pD est,
GetType(Int64)) )

Dim byteSize As Int32 = CInt(BitmapSize / 8)
byteSize += 1 ' round up - even with no remainder

Dim BitmapBegin As IntPtr = CType(CLng(pDes t) + 8, IntPtr)

Dim byteArr As Byte() = New Byte(byteSize - 1) {}

Marshal.Copy(Bi tmapBegin, byteArr, 0, CInt(byteSize))

Dim retVal As BitArray = New BitArray(byteAr r)
retVal.Length = CInt(BitmapSize ) ' truncate to exact cluster count
Return retVal
Finally
CloseHandle(hDe vice)
hDevice = IntPtr.Zero

Marshal.FreeHGl obal(pAlloc)
pAlloc = IntPtr.Zero
End Try
End Function

''' <summary>
''' returns a 2*number of extents array -
''' the vcn and the lcn as pairs
''' </summary>
''' <param name="path">fil e to get the map for ex:
"c:\windows\exp lorer.exe" </param>
''' <returns>An array of [virtual cluster, physical cluster]</returns>
Shared Public Function GetFileMap(ByVa l path As String) As Array
Dim hFile As IntPtr = IntPtr.Zero
Dim pAlloc As IntPtr = IntPtr.Zero

Try
hFile = OpenFile(path)

Dim i64 As Int64 = 0

Dim handle As GCHandle = GCHandle.Alloc( i64, GCHandleType.Pi nned)
Dim p As IntPtr = handle.AddrOfPi nnedObject()

Dim q As System.UInt32 = 1024 * 1024 * 64 ' 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

Dim size As System.UInt32
pAlloc = Marshal.AllocHG lobal(CInt(q))
Dim pDest As IntPtr = pAlloc
Dim fResult As Boolean = DeviceIoControl (hFile,
FSConstants.FSC TL_GET_RETRIEVA L_POINTERS, p, CUInt(Marshal.S izeOf(i64)),
pDest, q, size, IntPtr.Zero)

If (Not fResult) Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If

handle.Free()

'
'returned back one of...
'typedef struct RETRIEVAL_POINT ERS_BUFFER {
'DWORD ExtentCount;
'LARGE_INTEGER StartingVcn;
'struct {
'LARGE_INTEGER NextVcn;
'LARGE_INTEGER Lcn;
'} Extents[1];
'} RETRIEVAL_POINT ERS_BUFFER, *PRETRIEVAL_POI NTERS_BUFFER;
'

Dim ExtentCount As Int32 = CInt(Marshal.Pt rToStructure(pD est,
GetType(Int32)) )

pDest = CType(CLng(pDes t) + 4, IntPtr)

Dim StartingVcn As Int64 = CLng(Marshal.Pt rToStructure(pD est,
GetType(Int64)) )

Debug.Assert(St artingVcn = 0)

pDest = CType(CLng(pDes t) + 8, IntPtr)

' now pDest points at an array of pairs of Int64s.

Dim retVal As Array = Array.CreateIns tance(GetType(I nt64), New
Integer(1) { ExtentCount, 2 })

For i As Integer = 0 To ExtentCount - 1
For j As Integer = 0 To 1
Dim v As Int64 = CLng(Marshal.Pt rToStructure(pD est, GetType(Int64)) )
retVal.SetValue (v, New Integer(1) { i, j })
pDest = CType(CLng(pDes t) + 8, IntPtr)
Next j
Next i

Return retVal
Finally
CloseHandle(hFi le)
hFile = IntPtr.Zero

Marshal.FreeHGl obal(pAlloc)
pAlloc = IntPtr.Zero
End Try
End Function

''' <summary>
''' input structure for use in MoveFile
''' </summary>
Private Structure MoveFileData
Public hFile As IntPtr
Public StartingVCN As Int64
Public StartingLCN As Int64
Public ClusterCount As Int32
End Structure

''' <summary>
''' move a virtual cluster for a file to a logical cluster on disk, repeat
for count clusters
''' </summary>
''' <param name="deviceNam e">device to move on"c:"</param>
''' <param name="path">fil e to muck with "c:\windows\exp lorer.exe"</param>
''' <param name="VCN">clus ter number in file to move</param>
''' <param name="LCN">clus ter on disk to move to</param>
''' <param name="count">fo r how many clusters</param>
Shared Public Sub MoveFile(ByVal deviceName As String, ByVal path As
String, ByVal VCN As Int64, ByVal LCN As Int64, ByVal count As Int32)
Dim hVol As IntPtr = IntPtr.Zero
Dim hFile As IntPtr = IntPtr.Zero
Try
hVol = OpenVolume(devi ceName)

hFile = OpenFile(path)
Dim mfd As MoveFileData = New MoveFileData()
mfd.hFile = hFile
mfd.StartingVCN = VCN
mfd.StartingLCN = LCN
mfd.ClusterCoun t = count

Dim handle As GCHandle = GCHandle.Alloc( mfd, GCHandleType.Pi nned)
Dim p As IntPtr = handle.AddrOfPi nnedObject()
Dim bufSize As System.UInt32 = CUInt(Marshal.S izeOf(mfd))
Dim size As System.UInt32

Dim fResult As Boolean = DeviceIoControl (hVol,
FSConstants.FSC TL_MOVE_FILE, p, bufSize, IntPtr.Zero, 0, size, IntPtr.Zero)

handle.Free()

If (Not fResult) Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
Finally
CloseHandle(hVo l)
CloseHandle(hFi le)
End Try
End Sub
End Class
''' <summary>
''' constants lifted from winioctl.h from platform sdk
''' </summary>
Friend Class FSConstants
Private Const FILE_DEVICE_FIL E_SYSTEM As System.UInt32 = &H00000009

Private Const METHOD_NEITHER As System.UInt32 = 3
Private Const METHOD_BUFFERED As System.UInt32

Private Const FILE_ANY_ACCESS As System.UInt32
Private Const FILE_SPECIAL_AC CESS As System.UInt32 = FILE_ANY_ACCESS

Public Shared FSCTL_GET_VOLUM E_BITMAP As System.UInt32 =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 27, METHOD_NEITHER, FILE_ANY_ACCESS )
Public Shared FSCTL_GET_RETRI EVAL_POINTERS As System.UInt32 =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 28, METHOD_NEITHER, FILE_ANY_ACCESS )
Public Shared FSCTL_MOVE_FILE As System.UInt32 =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 29, METHOD_BUFFERED , FILE_SPECIAL_AC CESS)

'TODO: INSTANT VB TODO TASK: Function is a keyword in VB.NET. Change the
name or use square brackets to override it:
Private Shared Function CTL_CODE(ByVal DeviceType As System.UInt32, ByVal
Function As System.UInt32, ByVal Method As System.UInt32, ByVal Access As
System.UInt32) As System.UInt32
Return ((DeviceType) << 16) Or ((Access) << 14) Or ((Function) << 2) Or
(Method)
End Function
End Class

End Namespace
"Jim Hubbard" wrote:
I have some C# code that is supposed to wrap the defrag APIs and I am trying
to convert it to VB.Net (2003). But, I keep having problems.

The C# code is relatively short, so I'll post it here.....

--------
//
// a set of simple C# wrappers over the NT Defragmenter APIs
//

//
// Refrences

//
// http://www.sysinternals.com/ntw2k/info/defrag.shtml
//
// msdn how-to
// ms-help://MS.MSDNQTR.2004 JUL.1033/fileio/base/defragmenting_f iles.htm
//
http://msdn.microsoft.com/library/de...ting_files.asp
//
// FSCTL_GET_VOLUM E_BITMAP
//
http://msdn.microsoft.com/library/de...ume_bitmap.asp
//
// interesting structures...
// FSCTL_MOVE_FILE
// FSCTL_GET_RETRI EVAL_POINTERS
// RETRIEVAL_POINT ERS_BUFFER
// FSCTL_GET_RETRI EVAL_POINTERS
//
// DeviceIoControl
//
http://msdn.microsoft.com/library/de...eiocontrol.asp
//

using System;
using System.Diagnost ics;
using System.Collecti ons;
using System.Runtime. InteropServices ;

namespace defraglib
{
public class IOWrapper
{

//
// CreateFile constants
//
const uint FILE_SHARE_READ = 0x00000001;
const uint FILE_SHARE_WRIT E = 0x00000002;
const uint FILE_SHARE_DELE TE = 0x00000004;
const uint OPEN_EXISTING = 3;

const uint GENERIC_READ = (0x80000000);
const uint GENERIC_WRITE = (0x40000000);

const uint FILE_FLAG_NO_BU FFERING = 0x20000000;
const uint FILE_READ_ATTRI BUTES = (0x0080);
const uint FILE_WRITE_ATTR IBUTES = 0x0100;
const uint ERROR_INSUFFICI ENT_BUFFER = 122;

[DllImport("kern el32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess ,
uint dwShareMode,
IntPtr lpSecurityAttri butes,
uint dwCreationDispo sition,
uint dwFlagsAndAttri butes,
IntPtr hTemplateFile);

[DllImport("kern el32.dll", SetLastError = true)]
static extern int CloseHandle(Int Ptr hObject);

[DllImport("kern el32.dll", SetLastError = true)]
static extern bool DeviceIoControl (
IntPtr hDevice,
uint dwIoControlCode ,
IntPtr lpInBuffer,
uint nInBufferSize,
[Out] IntPtr lpOutBuffer,
uint nOutBufferSize,
ref uint lpBytesReturned ,
IntPtr lpOverlapped);

static private IntPtr OpenVolume(stri ng DeviceName)
{
IntPtr hDevice;
hDevice = CreateFile(
@"\\.\" + DeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRIT E,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hDevice == -1)
{
throw new Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
return hDevice;
}

static private IntPtr OpenFile(string path)
{
IntPtr hFile;
hFile = CreateFile(
path,
FILE_READ_ATTRI BUTES | FILE_WRITE_ATTR IBUTES,
FILE_SHARE_READ | FILE_SHARE_WRIT E,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hFile == -1)
{
throw new Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
return hFile;
}
/// <summary>
/// Get cluster usage for a device
/// </summary>
/// <param name="DeviceNam e">use "c:"</param>
/// <returns>a bitarray for each cluster</returns>
static public BitArray GetVolumeMap(st ring DeviceName)
{
IntPtr pAlloc = IntPtr.Zero;
IntPtr hDevice = IntPtr.Zero;

try
{
hDevice = OpenVolume(Devi ceName);

Int64 i64 = 0;

GCHandle handle = GCHandle.Alloc( i64, GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();

// alloc off more than enough for my machine
// 64 megs == 67108864 bytes == 536870912 bits == cluster
count
// NTFS 4k clusters == 2147483648 k of storage == 2097152
megs == 2048 gig disk storage
uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

uint size = 0;
pAlloc = Marshal.AllocHG lobal((int)q);
IntPtr pDest = pAlloc;

bool fResult = DeviceIoControl (
hDevice,
FSConstants.FSC TL_GET_VOLUME_B ITMAP,
p,
(uint)Marshal.S izeOf(i64),
pDest,
q,
ref size,
IntPtr.Zero);

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
handle.Free();

/*
object returned was...
typedef struct
{
LARGE_INTEGER StartingLcn;
LARGE_INTEGER BitmapSize;
BYTE Buffer[1];
} VOLUME_BITMAP_B UFFER, *PVOLUME_BITMAP _BUFFER;
*/
Int64 StartingLcn = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Debug.Assert(St artingLcn == 0);

pDest = (IntPtr)((Int64 )pDest + 8);
Int64 BitmapSize = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Int32 byteSize = (int)(BitmapSiz e / 8);
byteSize++; // round up - even with no remainder

IntPtr BitmapBegin = (IntPtr)((Int64 )pDest + 8);

byte[] byteArr = new byte[byteSize];

Marshal.Copy(Bi tmapBegin, byteArr, 0, (Int32)byteSize );

BitArray retVal = new BitArray(byteAr r);
retVal.Length = (int)BitmapSize ; // truncate to exact
cluster count
return retVal;
}
finally
{
CloseHandle(hDe vice);
hDevice = IntPtr.Zero;

Marshal.FreeHGl obal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

/// <summary>
/// returns a 2*number of extents array -
/// the vcn and the lcn as pairs
/// </summary>
/// <param name="path">fil e to get the map for ex:
"c:\windows\exp lorer.exe" </param>
/// <returns>An array of [virtual cluster, physical
cluster]</returns>
static public Array GetFileMap(stri ng path)
{
IntPtr hFile = IntPtr.Zero;
IntPtr pAlloc = IntPtr.Zero;

try
{
hFile = OpenFile(path);

Int64 i64 = 0;

GCHandle handle = GCHandle.Alloc( i64, GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();

uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

uint size = 0;
pAlloc = Marshal.AllocHG lobal((int)q);
IntPtr pDest = pAlloc;
bool fResult = DeviceIoControl (
hFile,
FSConstants.FSC TL_GET_RETRIEVA L_POINTERS,
p,
(uint)Marshal.S izeOf(i64),
pDest,
q,
ref size,
IntPtr.Zero);

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}

handle.Free();

/*
returned back one of...
typedef struct RETRIEVAL_POINT ERS_BUFFER {
DWORD ExtentCount;
LARGE_INTEGER StartingVcn;
struct {
LARGE_INTEGER NextVcn;
LARGE_INTEGER Lcn;
} Extents[1];
} RETRIEVAL_POINT ERS_BUFFER, *PRETRIEVAL_POI NTERS_BUFFER;
*/

Int32 ExtentCount = (Int32)Marshal. PtrToStructure( pDest,
typeof(Int32));

pDest = (IntPtr)((Int64 )pDest + 4);

Int64 StartingVcn = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Debug.Assert(St artingVcn == 0);

pDest = (IntPtr)((Int64 )pDest + 8);

// now pDest points at an array of pairs of Int64s.

Array retVal = Array.CreateIns tance(typeof(In t64), new
int[2] { ExtentCount, 2 });

for (int i = 0; i < ExtentCount; i++)
{
for (int j = 0; j < 2; j++)
{
Int64 v = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));
retVal.SetValue (v, new int[2] { i, j });
pDest = (IntPtr)((Int64 )pDest + 8);
}
}

return retVal;
}
finally
{
CloseHandle(hFi le);
hFile = IntPtr.Zero;

Marshal.FreeHGl obal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

/// <summary>
/// input structure for use in MoveFile
/// </summary>
private struct MoveFileData
{
public IntPtr hFile;
public Int64 StartingVCN;
public Int64 StartingLCN;
public Int32 ClusterCount;
}

/// <summary>
/// move a virtual cluster for a file to a logical cluster on disk,
repeat for count clusters
/// </summary>
/// <param name="deviceNam e">device to move on"c:"</param>
/// <param name="path">fil e to muck with
"c:\windows\exp lorer.exe"</param>
/// <param name="VCN">clus ter number in file to move</param>
/// <param name="LCN">clus ter on disk to move to</param>
/// <param name="count">fo r how many clusters</param>
static public void MoveFile(string deviceName, string path, Int64
VCN, Int64 LCN, Int32 count)
{
IntPtr hVol = IntPtr.Zero;
IntPtr hFile = IntPtr.Zero;
try
{
hVol = OpenVolume(devi ceName);

hFile = OpenFile(path);
MoveFileData mfd = new MoveFileData();
mfd.hFile = hFile;
mfd.StartingVCN = VCN;
mfd.StartingLCN = LCN;
mfd.ClusterCoun t = count;

GCHandle handle = GCHandle.Alloc( mfd, GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();
uint bufSize = (uint)Marshal.S izeOf(mfd);
uint size = 0;

bool fResult = DeviceIoControl (
hVol,
FSConstants.FSC TL_MOVE_FILE,
p,
bufSize,
IntPtr.Zero, // no output data from this FSCTL
0,
ref size,
IntPtr.Zero);

handle.Free();

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
}
finally
{
CloseHandle(hVo l);
CloseHandle(hFi le);
}
}
}
/// <summary>
/// constants lifted from winioctl.h from platform sdk
/// </summary>
internal class FSConstants
{
const uint FILE_DEVICE_FIL E_SYSTEM = 0x00000009;

const uint METHOD_NEITHER = 3;
const uint METHOD_BUFFERED = 0;

const uint FILE_ANY_ACCESS = 0;
const uint FILE_SPECIAL_AC CESS = FILE_ANY_ACCESS ;

public static uint FSCTL_GET_VOLUM E_BITMAP =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 27, METHOD_NEITHER, FILE_ANY_ACCESS );
public static uint FSCTL_GET_RETRI EVAL_POINTERS =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 28, METHOD_NEITHER, FILE_ANY_ACCESS );
public static uint FSCTL_MOVE_FILE =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 29, METHOD_BUFFERED , FILE_SPECIAL_AC CESS);

static uint CTL_CODE(uint DeviceType, uint Function, uint Method,
uint Access)
{
return ((DeviceType) << 16) | ((Access) << 14) | ((Function) <<
2) | (Method);
}
}

}

-----

I'd be very grateful for any help with this conversion that you could offer.

Thanks!


Nov 16 '05 #5
David! That's awesome!

Better than anything I've seen!

Thanks!

"David Anton" <Da********@dis cussions.micros oft.com> wrote in message
news:AD******** *************** ***********@mic rosoft.com...
Our Instant VB converter yields the following:
(feel free to download our Demo Edition at www.instantvb.com - it's the
only
C# to VB converter that is fully supported)

Imports System
Imports System.Diagnost ics
Imports System.Collecti ons
Imports System.Runtime. InteropServices

Namespace defraglib
Public Class IOWrapper

'
' CreateFile constants
'
Private Const FILE_SHARE_READ As System.UInt32 = &H00000001
Private Const FILE_SHARE_WRIT E As System.UInt32 = &H00000002
Private Const FILE_SHARE_DELE TE As System.UInt32 = &H00000004
Private Const OPEN_EXISTING As System.UInt32 = 3

Private Const GENERIC_READ As System.UInt32 = (&H80000000)
Private Const GENERIC_WRITE As System.UInt32 = (&H40000000)

Private Const FILE_FLAG_NO_BU FFERING As System.UInt32 = &H20000000
Private Const FILE_READ_ATTRI BUTES As System.UInt32 = (&H0080)
Private Const FILE_WRITE_ATTR IBUTES As System.UInt32 = &H0100
Private Const ERROR_INSUFFICI ENT_BUFFER As System.UInt32 = 122

<DllImport("ker nel32.dll", SetLastError := True)> _
Shared Function CreateFile(ByVa l lpFileName As String, ByVal
dwDesiredAccess As System.UInt32, ByVal dwShareMode As System.UInt32,
ByVal
lpSecurityAttri butes As IntPtr, ByVal dwCreationDispo sition As
System.UInt32,
ByVal dwFlagsAndAttri butes As System.UInt32, ByVal hTemplateFile As
IntPtr)
As IntPtr
End Function

<DllImport("ker nel32.dll", SetLastError := True)> _
Shared Function CloseHandle(ByV al hObject As IntPtr) As Integer
End Function

<DllImport("ker nel32.dll", SetLastError := True)> _
Shared Function DeviceIoControl (ByVal hDevice As IntPtr, ByVal
dwIoControlCode As System.UInt32, ByVal lpInBuffer As IntPtr, ByVal
nInBufferSize As System.UInt32, <Out> ByVal lpOutBuffer As IntPtr, ByVal
nOutBufferSize As System.UInt32, ByRef lpBytesReturned As System.UInt32,
ByVal lpOverlapped As IntPtr) As Boolean
End Function

Shared Private Function OpenVolume(ByVa l DeviceName As String) As IntPtr
Dim hDevice As IntPtr
hDevice = CreateFile("\\. \" + DeviceName, GENERIC_READ Or GENERIC_WRITE,
FILE_SHARE_WRIT E, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)
If CInt(hDevice) = -1 Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
Return hDevice
End Function

Shared Private Function OpenFile(ByVal path As String) As IntPtr
Dim hFile As IntPtr
hFile = CreateFile(path , FILE_READ_ATTRI BUTES Or FILE_WRITE_ATTR IBUTES,
FILE_SHARE_READ Or FILE_SHARE_WRIT E, IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero)
If CInt(hFile) = -1 Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
Return hFile
End Function
''' <summary>
''' Get cluster usage for a device
''' </summary>
''' <param name="DeviceNam e">use "c:"</param>
''' <returns>a bitarray for each cluster</returns>
Shared Public Function GetVolumeMap(By Val DeviceName As String) As
BitArray
Dim pAlloc As IntPtr = IntPtr.Zero
Dim hDevice As IntPtr = IntPtr.Zero

Try
hDevice = OpenVolume(Devi ceName)

Dim i64 As Int64 = 0

Dim handle As GCHandle = GCHandle.Alloc( i64, GCHandleType.Pi nned)
Dim p As IntPtr = handle.AddrOfPi nnedObject()

' alloc off more than enough for my machine
' 64 megs == 67108864 bytes == 536870912 bits == cluster count
' NTFS 4k clusters == 2147483648 k of storage == 2097152 megs == 2048
gig disk storage
Dim q As System.UInt32 = 1024 * 1024 * 64 ' 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

Dim size As System.UInt32
pAlloc = Marshal.AllocHG lobal(CInt(q))
Dim pDest As IntPtr = pAlloc

Dim fResult As Boolean = DeviceIoControl (hDevice,
FSConstants.FSC TL_GET_VOLUME_B ITMAP, p, CUInt(Marshal.S izeOf(i64)), pDest,
q,
size, IntPtr.Zero)

If (Not fResult) Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
handle.Free()

'
'object returned was...
'typedef struct
'{
'LARGE_INTEGER StartingLcn;
'LARGE_INTEGER BitmapSize;
'BYTE Buffer[1];
'} VOLUME_BITMAP_B UFFER, *PVOLUME_BITMAP _BUFFER;
'
Dim StartingLcn As Int64 = CLng(Marshal.Pt rToStructure(pD est,
GetType(Int64)) )

Debug.Assert(St artingLcn = 0)

pDest = CType(CLng(pDes t) + 8, IntPtr)
Dim BitmapSize As Int64 = CLng(Marshal.Pt rToStructure(pD est,
GetType(Int64)) )

Dim byteSize As Int32 = CInt(BitmapSize / 8)
byteSize += 1 ' round up - even with no remainder

Dim BitmapBegin As IntPtr = CType(CLng(pDes t) + 8, IntPtr)

Dim byteArr As Byte() = New Byte(byteSize - 1) {}

Marshal.Copy(Bi tmapBegin, byteArr, 0, CInt(byteSize))

Dim retVal As BitArray = New BitArray(byteAr r)
retVal.Length = CInt(BitmapSize ) ' truncate to exact cluster count
Return retVal
Finally
CloseHandle(hDe vice)
hDevice = IntPtr.Zero

Marshal.FreeHGl obal(pAlloc)
pAlloc = IntPtr.Zero
End Try
End Function

''' <summary>
''' returns a 2*number of extents array -
''' the vcn and the lcn as pairs
''' </summary>
''' <param name="path">fil e to get the map for ex:
"c:\windows\exp lorer.exe" </param>
''' <returns>An array of [virtual cluster, physical cluster]</returns>
Shared Public Function GetFileMap(ByVa l path As String) As Array
Dim hFile As IntPtr = IntPtr.Zero
Dim pAlloc As IntPtr = IntPtr.Zero

Try
hFile = OpenFile(path)

Dim i64 As Int64 = 0

Dim handle As GCHandle = GCHandle.Alloc( i64, GCHandleType.Pi nned)
Dim p As IntPtr = handle.AddrOfPi nnedObject()

Dim q As System.UInt32 = 1024 * 1024 * 64 ' 1024 bytes == 1k * 1024 == 1
meg * 64 == 64 megs

Dim size As System.UInt32
pAlloc = Marshal.AllocHG lobal(CInt(q))
Dim pDest As IntPtr = pAlloc
Dim fResult As Boolean = DeviceIoControl (hFile,
FSConstants.FSC TL_GET_RETRIEVA L_POINTERS, p, CUInt(Marshal.S izeOf(i64)),
pDest, q, size, IntPtr.Zero)

If (Not fResult) Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If

handle.Free()

'
'returned back one of...
'typedef struct RETRIEVAL_POINT ERS_BUFFER {
'DWORD ExtentCount;
'LARGE_INTEGER StartingVcn;
'struct {
'LARGE_INTEGER NextVcn;
'LARGE_INTEGER Lcn;
'} Extents[1];
'} RETRIEVAL_POINT ERS_BUFFER, *PRETRIEVAL_POI NTERS_BUFFER;
'

Dim ExtentCount As Int32 = CInt(Marshal.Pt rToStructure(pD est,
GetType(Int32)) )

pDest = CType(CLng(pDes t) + 4, IntPtr)

Dim StartingVcn As Int64 = CLng(Marshal.Pt rToStructure(pD est,
GetType(Int64)) )

Debug.Assert(St artingVcn = 0)

pDest = CType(CLng(pDes t) + 8, IntPtr)

' now pDest points at an array of pairs of Int64s.

Dim retVal As Array = Array.CreateIns tance(GetType(I nt64), New
Integer(1) { ExtentCount, 2 })

For i As Integer = 0 To ExtentCount - 1
For j As Integer = 0 To 1
Dim v As Int64 = CLng(Marshal.Pt rToStructure(pD est, GetType(Int64)) )
retVal.SetValue (v, New Integer(1) { i, j })
pDest = CType(CLng(pDes t) + 8, IntPtr)
Next j
Next i

Return retVal
Finally
CloseHandle(hFi le)
hFile = IntPtr.Zero

Marshal.FreeHGl obal(pAlloc)
pAlloc = IntPtr.Zero
End Try
End Function

''' <summary>
''' input structure for use in MoveFile
''' </summary>
Private Structure MoveFileData
Public hFile As IntPtr
Public StartingVCN As Int64
Public StartingLCN As Int64
Public ClusterCount As Int32
End Structure

''' <summary>
''' move a virtual cluster for a file to a logical cluster on disk, repeat
for count clusters
''' </summary>
''' <param name="deviceNam e">device to move on"c:"</param>
''' <param name="path">fil e to muck with "c:\windows\exp lorer.exe"</param>
''' <param name="VCN">clus ter number in file to move</param>
''' <param name="LCN">clus ter on disk to move to</param>
''' <param name="count">fo r how many clusters</param>
Shared Public Sub MoveFile(ByVal deviceName As String, ByVal path As
String, ByVal VCN As Int64, ByVal LCN As Int64, ByVal count As Int32)
Dim hVol As IntPtr = IntPtr.Zero
Dim hFile As IntPtr = IntPtr.Zero
Try
hVol = OpenVolume(devi ceName)

hFile = OpenFile(path)
Dim mfd As MoveFileData = New MoveFileData()
mfd.hFile = hFile
mfd.StartingVCN = VCN
mfd.StartingLCN = LCN
mfd.ClusterCoun t = count

Dim handle As GCHandle = GCHandle.Alloc( mfd, GCHandleType.Pi nned)
Dim p As IntPtr = handle.AddrOfPi nnedObject()
Dim bufSize As System.UInt32 = CUInt(Marshal.S izeOf(mfd))
Dim size As System.UInt32

Dim fResult As Boolean = DeviceIoControl (hVol,
FSConstants.FSC TL_MOVE_FILE, p, bufSize, IntPtr.Zero, 0, size,
IntPtr.Zero)

handle.Free()

If (Not fResult) Then
Throw New Exception(Marsh al.GetLastWin32 Error().ToStrin g())
End If
Finally
CloseHandle(hVo l)
CloseHandle(hFi le)
End Try
End Sub
End Class
''' <summary>
''' constants lifted from winioctl.h from platform sdk
''' </summary>
Friend Class FSConstants
Private Const FILE_DEVICE_FIL E_SYSTEM As System.UInt32 = &H00000009

Private Const METHOD_NEITHER As System.UInt32 = 3
Private Const METHOD_BUFFERED As System.UInt32

Private Const FILE_ANY_ACCESS As System.UInt32
Private Const FILE_SPECIAL_AC CESS As System.UInt32 = FILE_ANY_ACCESS

Public Shared FSCTL_GET_VOLUM E_BITMAP As System.UInt32 =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 27, METHOD_NEITHER, FILE_ANY_ACCESS )
Public Shared FSCTL_GET_RETRI EVAL_POINTERS As System.UInt32 =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 28, METHOD_NEITHER, FILE_ANY_ACCESS )
Public Shared FSCTL_MOVE_FILE As System.UInt32 =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 29, METHOD_BUFFERED ,
FILE_SPECIAL_AC CESS)

'TODO: INSTANT VB TODO TASK: Function is a keyword in VB.NET. Change the
name or use square brackets to override it:
Private Shared Function CTL_CODE(ByVal DeviceType As System.UInt32, ByVal
Function As System.UInt32, ByVal Method As System.UInt32, ByVal Access As
System.UInt32) As System.UInt32
Return ((DeviceType) << 16) Or ((Access) << 14) Or ((Function) << 2) Or
(Method)
End Function
End Class

End Namespace
"Jim Hubbard" wrote:
I have some C# code that is supposed to wrap the defrag APIs and I am
trying
to convert it to VB.Net (2003). But, I keep having problems.

The C# code is relatively short, so I'll post it here.....

--------
//
// a set of simple C# wrappers over the NT Defragmenter APIs
//

//
// Refrences

//
// http://www.sysinternals.com/ntw2k/info/defrag.shtml
//
// msdn how-to
// ms-help://MS.MSDNQTR.2004 JUL.1033/fileio/base/defragmenting_f iles.htm
//
http://msdn.microsoft.com/library/de...ting_files.asp
//
// FSCTL_GET_VOLUM E_BITMAP
//
http://msdn.microsoft.com/library/de...ume_bitmap.asp
//
// interesting structures...
// FSCTL_MOVE_FILE
// FSCTL_GET_RETRI EVAL_POINTERS
// RETRIEVAL_POINT ERS_BUFFER
// FSCTL_GET_RETRI EVAL_POINTERS
//
// DeviceIoControl
//
http://msdn.microsoft.com/library/de...eiocontrol.asp
//

using System;
using System.Diagnost ics;
using System.Collecti ons;
using System.Runtime. InteropServices ;

namespace defraglib
{
public class IOWrapper
{

//
// CreateFile constants
//
const uint FILE_SHARE_READ = 0x00000001;
const uint FILE_SHARE_WRIT E = 0x00000002;
const uint FILE_SHARE_DELE TE = 0x00000004;
const uint OPEN_EXISTING = 3;

const uint GENERIC_READ = (0x80000000);
const uint GENERIC_WRITE = (0x40000000);

const uint FILE_FLAG_NO_BU FFERING = 0x20000000;
const uint FILE_READ_ATTRI BUTES = (0x0080);
const uint FILE_WRITE_ATTR IBUTES = 0x0100;
const uint ERROR_INSUFFICI ENT_BUFFER = 122;

[DllImport("kern el32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess ,
uint dwShareMode,
IntPtr lpSecurityAttri butes,
uint dwCreationDispo sition,
uint dwFlagsAndAttri butes,
IntPtr hTemplateFile);

[DllImport("kern el32.dll", SetLastError = true)]
static extern int CloseHandle(Int Ptr hObject);

[DllImport("kern el32.dll", SetLastError = true)]
static extern bool DeviceIoControl (
IntPtr hDevice,
uint dwIoControlCode ,
IntPtr lpInBuffer,
uint nInBufferSize,
[Out] IntPtr lpOutBuffer,
uint nOutBufferSize,
ref uint lpBytesReturned ,
IntPtr lpOverlapped);

static private IntPtr OpenVolume(stri ng DeviceName)
{
IntPtr hDevice;
hDevice = CreateFile(
@"\\.\" + DeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRIT E,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hDevice == -1)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
return hDevice;
}

static private IntPtr OpenFile(string path)
{
IntPtr hFile;
hFile = CreateFile(
path,
FILE_READ_ATTRI BUTES | FILE_WRITE_ATTR IBUTES,
FILE_SHARE_READ | FILE_SHARE_WRIT E,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hFile == -1)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
return hFile;
}
/// <summary>
/// Get cluster usage for a device
/// </summary>
/// <param name="DeviceNam e">use "c:"</param>
/// <returns>a bitarray for each cluster</returns>
static public BitArray GetVolumeMap(st ring DeviceName)
{
IntPtr pAlloc = IntPtr.Zero;
IntPtr hDevice = IntPtr.Zero;

try
{
hDevice = OpenVolume(Devi ceName);

Int64 i64 = 0;

GCHandle handle = GCHandle.Alloc( i64,
GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();

// alloc off more than enough for my machine
// 64 megs == 67108864 bytes == 536870912 bits == cluster
count
// NTFS 4k clusters == 2147483648 k of storage == 2097152
megs == 2048 gig disk storage
uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 ==
1
meg * 64 == 64 megs

uint size = 0;
pAlloc = Marshal.AllocHG lobal((int)q);
IntPtr pDest = pAlloc;

bool fResult = DeviceIoControl (
hDevice,
FSConstants.FSC TL_GET_VOLUME_B ITMAP,
p,
(uint)Marshal.S izeOf(i64),
pDest,
q,
ref size,
IntPtr.Zero);

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
handle.Free();

/*
object returned was...
typedef struct
{
LARGE_INTEGER StartingLcn;
LARGE_INTEGER BitmapSize;
BYTE Buffer[1];
} VOLUME_BITMAP_B UFFER, *PVOLUME_BITMAP _BUFFER;
*/
Int64 StartingLcn = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Debug.Assert(St artingLcn == 0);

pDest = (IntPtr)((Int64 )pDest + 8);
Int64 BitmapSize = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Int32 byteSize = (int)(BitmapSiz e / 8);
byteSize++; // round up - even with no remainder

IntPtr BitmapBegin = (IntPtr)((Int64 )pDest + 8);

byte[] byteArr = new byte[byteSize];

Marshal.Copy(Bi tmapBegin, byteArr, 0, (Int32)byteSize );

BitArray retVal = new BitArray(byteAr r);
retVal.Length = (int)BitmapSize ; // truncate to exact
cluster count
return retVal;
}
finally
{
CloseHandle(hDe vice);
hDevice = IntPtr.Zero;

Marshal.FreeHGl obal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

/// <summary>
/// returns a 2*number of extents array -
/// the vcn and the lcn as pairs
/// </summary>
/// <param name="path">fil e to get the map for ex:
"c:\windows\exp lorer.exe" </param>
/// <returns>An array of [virtual cluster, physical
cluster]</returns>
static public Array GetFileMap(stri ng path)
{
IntPtr hFile = IntPtr.Zero;
IntPtr pAlloc = IntPtr.Zero;

try
{
hFile = OpenFile(path);

Int64 i64 = 0;

GCHandle handle = GCHandle.Alloc( i64,
GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();

uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 ==
1
meg * 64 == 64 megs

uint size = 0;
pAlloc = Marshal.AllocHG lobal((int)q);
IntPtr pDest = pAlloc;
bool fResult = DeviceIoControl (
hFile,
FSConstants.FSC TL_GET_RETRIEVA L_POINTERS,
p,
(uint)Marshal.S izeOf(i64),
pDest,
q,
ref size,
IntPtr.Zero);

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}

handle.Free();

/*
returned back one of...
typedef struct RETRIEVAL_POINT ERS_BUFFER {
DWORD ExtentCount;
LARGE_INTEGER StartingVcn;
struct {
LARGE_INTEGER NextVcn;
LARGE_INTEGER Lcn;
} Extents[1];
} RETRIEVAL_POINT ERS_BUFFER, *PRETRIEVAL_POI NTERS_BUFFER;
*/

Int32 ExtentCount = (Int32)Marshal. PtrToStructure( pDest,
typeof(Int32));

pDest = (IntPtr)((Int64 )pDest + 4);

Int64 StartingVcn = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));

Debug.Assert(St artingVcn == 0);

pDest = (IntPtr)((Int64 )pDest + 8);

// now pDest points at an array of pairs of Int64s.

Array retVal = Array.CreateIns tance(typeof(In t64), new
int[2] { ExtentCount, 2 });

for (int i = 0; i < ExtentCount; i++)
{
for (int j = 0; j < 2; j++)
{
Int64 v = (Int64)Marshal. PtrToStructure( pDest,
typeof(Int64));
retVal.SetValue (v, new int[2] { i, j });
pDest = (IntPtr)((Int64 )pDest + 8);
}
}

return retVal;
}
finally
{
CloseHandle(hFi le);
hFile = IntPtr.Zero;

Marshal.FreeHGl obal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

/// <summary>
/// input structure for use in MoveFile
/// </summary>
private struct MoveFileData
{
public IntPtr hFile;
public Int64 StartingVCN;
public Int64 StartingLCN;
public Int32 ClusterCount;
}

/// <summary>
/// move a virtual cluster for a file to a logical cluster on
disk,
repeat for count clusters
/// </summary>
/// <param name="deviceNam e">device to move on"c:"</param>
/// <param name="path">fil e to muck with
"c:\windows\exp lorer.exe"</param>
/// <param name="VCN">clus ter number in file to move</param>
/// <param name="LCN">clus ter on disk to move to</param>
/// <param name="count">fo r how many clusters</param>
static public void MoveFile(string deviceName, string path, Int64
VCN, Int64 LCN, Int32 count)
{
IntPtr hVol = IntPtr.Zero;
IntPtr hFile = IntPtr.Zero;
try
{
hVol = OpenVolume(devi ceName);

hFile = OpenFile(path);
MoveFileData mfd = new MoveFileData();
mfd.hFile = hFile;
mfd.StartingVCN = VCN;
mfd.StartingLCN = LCN;
mfd.ClusterCoun t = count;

GCHandle handle = GCHandle.Alloc( mfd,
GCHandleType.Pi nned);
IntPtr p = handle.AddrOfPi nnedObject();
uint bufSize = (uint)Marshal.S izeOf(mfd);
uint size = 0;

bool fResult = DeviceIoControl (
hVol,
FSConstants.FSC TL_MOVE_FILE,
p,
bufSize,
IntPtr.Zero, // no output data from this FSCTL
0,
ref size,
IntPtr.Zero);

handle.Free();

if (!fResult)
{
throw new
Exception(Marsh al.GetLastWin32 Error().ToStrin g());
}
}
finally
{
CloseHandle(hVo l);
CloseHandle(hFi le);
}
}
}
/// <summary>
/// constants lifted from winioctl.h from platform sdk
/// </summary>
internal class FSConstants
{
const uint FILE_DEVICE_FIL E_SYSTEM = 0x00000009;

const uint METHOD_NEITHER = 3;
const uint METHOD_BUFFERED = 0;

const uint FILE_ANY_ACCESS = 0;
const uint FILE_SPECIAL_AC CESS = FILE_ANY_ACCESS ;

public static uint FSCTL_GET_VOLUM E_BITMAP =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 27, METHOD_NEITHER, FILE_ANY_ACCESS );
public static uint FSCTL_GET_RETRI EVAL_POINTERS =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 28, METHOD_NEITHER, FILE_ANY_ACCESS );
public static uint FSCTL_MOVE_FILE =
CTL_CODE(FILE_D EVICE_FILE_SYST EM, 29, METHOD_BUFFERED ,
FILE_SPECIAL_AC CESS);

static uint CTL_CODE(uint DeviceType, uint Function, uint Method,
uint Access)
{
return ((DeviceType) << 16) | ((Access) << 14) | ((Function)
<<
2) | (Method);
}
}

}

-----

I'd be very grateful for any help with this conversion that you could
offer.

Thanks!


Nov 16 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
3976
by: Philipp Lenssen | last post by:
I want to write a third installment of "Little Known HTML Facts"*. I would appreciate your input here. For one thing, I would like to remember what exactly those proprietary icons were you could use -- I believe something like "&happyface;" would display a happy face, and so on, for folders, disk drives, and other technical icons. I found something called "&folder;" and "&audio;" (straight from the horse's mouth, at the W3C) but can't...
3
5193
by: gary | last post by:
Hi, 1. About all C/C++ compilers, Does stack increase from high address to low address and heap grow increase from low to high? What on earth decides their increase direction, CPU architecture, OS or compiler? 2. In GNU gcc, { int a = {0, 1, 2, 3, 4}; bool b; float c; for (int i = 0; i < 5; i++) {
1
2498
by: MLH | last post by:
The text below was cut 'n past from an HTML file. When I pasted it into a text field of an Access 97 table, it looked different than it does below. Below, you can see that the first 3 lines have hard returns at the end of each line (carriage return and line feed). But what I see pasted into an A97 table field is a single string with little square boxes at the ends of these lines. I see VIN:, a box, then 12 spaces, then </strong>,
38
3369
by: Martin Marcher | last post by:
Hi, I've read several questions and often the answer was 'C knows nothing about .' So if C knows that little as some people say, what are the benefits, I mean do other languages know more or is it a benefit that C knows nearly nothing (what I can think about is that C is the largest common divisor defined on most available platforms)?
0
1198
by: Kenneth Lantrip | last post by:
After some cleaning of some of my personal directories and files, I stumbled upon this little program I wrote some time ago. A scammer was trying to introduce me into his little pyramid scam. So to prove it was a bad idea, I decided to write this little program to find some confidence in the dicision to not get mixed up in his plot to rule the world. Anyway, Here is the program for your amusement. I only had to change a couple of...
2
6551
by: bhatia | last post by:
Hello all, If I have a C-like data structure such that struct Data { int a; //16-bit value char; //3 ASCII characters int b; //32-bit value int c; //24-bit value }
5
3150
by: manishster | last post by:
I keep getting the following in my output file , regardless of whether I convert endian-ness or not . How do i get "01 02 03 04" .... Mahamannu output : 04 03 02 01 b0 00 00
13
27311
by: junky_fellow | last post by:
Hi guys, I need to convert a big endian integer to little endian integer. (the integer is 4 bytes in size on my implementation). I came up with the following code. I need your comments on this. Please suggest any improvements that can be done. #include <stdio.h> int main(void) {
102
5172
by: BoogieWithStu22 | last post by:
I am running into a problem with a web page I have created when viewing it in IE6 on some machines. The page has a database lookup. The user enters an account name or number and clicks a lookup button. This hits an AS400 database looks for matches and returns a dataset that is used to populate a datagrid. The user then selects one of the entries from the list, this entry is used to populate a couple of textboxes on the page and a couple...
23
7051
by: Niranjan | last post by:
I have this program : void main() { int i=1; if((*(char*)&i)==1) printf("The machine is little endian."); else printf("The machine is big endian."); }
0
9687
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9541
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10485
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10252
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10231
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7565
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6805
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4141
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2938
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.