PC Review


Reply
Thread Tools Rate Thread

DeviceIOControl works but output buffer contains all zeros

 
 
=?Utf-8?B?UGl4aWU=?=
Guest
Posts: n/a
 
      13th Jul 2004
I am trying to query the change journal using the deviceIOControl API. The API doesn't return an error, but all of the values in the output buffer are zero, and they shouldn't be. My code is below. I have also tried specifying different pack values in my USN_JOURNAL_DATA structure definition but this didn't change anything. Any help would be greatly appreciated

Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const OPEN_EXISTING = 3
Private Const METHOD_BUFFERED = &H0
Private Const FILE_DEVICE_FILE_SYSTEM = &H9
Private Const FILE_ANY_ACCESS = &H0
Private Const FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> Public Structure USN_JOURNAL_DATA
Public UsnJournalID As Long
Public FirstUsn As Int64
Public NextUsn As Int64
Public LowestValidUsn As Int64
Public MaxUsn As Int64
Public MaximumSize As Long
Public AllocationDelta As Long
End Structure

Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal DesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Declare Auto Function DeviceIoControl Lib "kernel32.dll" (ByVal hDevice As Long, ByVal dwIoControlCode As Integer, ByVal lpInBuffer As Integer, ByVal nInBufferSize As Integer, <MarshalAs(UnmanagedType.Struct)> ByRef lpOutBuffer As USN_JOURNAL_DATA, ByVal nOutBufferSize As Integer, ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Long


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim FSCTL_QUERY_USN_JOURNAL As Long = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 61, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
Dim aHandle As Long
Dim anObject As Long
Dim byteBack As Long
Dim ujd As USN_JOURNAL_DATA

aHandle = CreateFile("\\.\I:", 0&, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&)
anObject = DeviceIoControl(aHandle, FSCTL_QUERY_USN_JOURNAL, 0, 0, ujd, Marshal.SizeOf(ujd), byteBack, 0)
If anObject = 0 Then
MsgBox(Marshal.GetLastWin32Error.ToString & Marshal.GetHRForLastWin32Error.ToString)
Else
MsgBox(ujd.UsnJournalID.ToString)
MsgBox(ujd.UsnJournalID)
MsgBox(ujd.FirstUsn)
MsgBox(ujd.NextUsn)
MsgBox(ujd.MaxUsn)
MsgBox(ujd.LowestValidUsn)
MsgBox(ujd.AllocationDelta)
MsgBox(ujd.MaximumSize)
End If
End Sub

Public Function CTL_CODE(ByVal DeviceType As Integer, ByVal Func As Integer, ByVal Method As Integer, ByVal Access As Integer) As Long
Return (DeviceType << 16) Or (Access << 14) Or (Func << 2) Or Method
End Function
 
Reply With Quote
 
 
 
 
Herfried K. Wagner [MVP]
Guest
Posts: n/a
 
      13th Jul 2004
* "=?Utf-8?B?UGl4aWU=?=" <(E-Mail Removed)> scripsit:
> <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> Public Structure USN_JOURNAL_DATA
> Public UsnJournalID As Long
> Public FirstUsn As Int64
> Public NextUsn As Int64
> Public LowestValidUsn As Int64
> Public MaxUsn As Int64
> Public MaximumSize As Long
> Public AllocationDelta As Long
> End Structure
>
> Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal DesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
>
> Declare Auto Function DeviceIoControl Lib "kernel32.dll" (ByVal hDevice As Long, ByVal dwIoControlCode As Integer, ByVal lpInBuffer As Integer, ByVal nInBufferSize As Integer, <MarshalAs(UnmanagedType.Struct)> ByRef lpOutBuffer As USN_JOURNAL_DATA, ByVal nOutBufferSize As Integer, ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Long


Notice that 'Long' is a 64-bit datatype in .NET, but 'DWORD' is 32-bit.
You will have to change some of the 'As Long' to 'As Int32'.

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>
 
Reply With Quote
 
New Member
Join Date: Oct 2005
Posts: 2
 
      20th Oct 2005
Thanks for the code which was helpful for me to translate (to VB6) and get started.

I can not read the records as the DeviceIoControl function always returns the error "The supplied user buffer is not valid for the requested operation.". I have tried creating the buffer in every way I can conceive of (local, global, module variables and heap) but can't see what is going wrong. A pointer to get me started again would be great.

Thanks,
Bruce

Code:
Private Declare Function DeviceIoControlA Lib "kernel32.dll" Alias "DeviceIoControl" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, ByVal lpOutBuffer As Long, ByVal nOutBufferSize As Long, ByRef lpBytesReturned As Long, lpOverlapped As OVERLAPPED) As Long

Private Type USN
    Lo As Long
    Hi As Long
End Type

Private Type CJDataType
    NextUsn As USN
    CJData(USN_PAGE_SIZE - 8) As Byte
End Type
Private CJData As CJDataType

Private Type READ_USN_JOURNAL_DATA
    StartUsn As USN
    ReasonMask As USN_REASONS
    ReturnOnlyOnClose As Boolean
    Timeout As Int64
    BytesToWaitFor As Int64
    UsnJournalID As Int64
End Type

Private Sub Form_Load()
Dim FSCTL_QUERY_USN_JOURNAL As Long
Dim FSCTL_READ_USN_JOURNAL As Long
Dim hCJ As Long
Dim ret As Long
Dim BytesReturned As Long
Dim ujd As USN_JOURNAL_DATA
Dim rujd As READ_USN_JOURNAL_DATA
Dim dPtr As Long, hHeap As Long
Dim CJData As CJDataType

    FSCTL_QUERY_USN_JOURNAL = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 61, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
    FSCTL_READ_USN_JOURNAL = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 46, METHOD_NEITHER, FILE_ANY_ACCESS)
    
    hHeap = GetProcessHeap()
    If hHeap = 0 Then Exit Sub
    dPtr = HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS Or HEAP_ZERO_MEMORY, USN_PAGE_SIZE)
    If dPtr = 0 Then
       Debug.Print "memory allocation failed!"
       Exit Sub
    Else
        Debug.Print Hex(dPtr) & " " & VarPtr(CJData)
        Debug.Print HeapSize(hHeap, 0, dPtr)
    End If
    
    hCJ = CreateFile("\\.\C:", GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&)
    
    ' Recall change cournal statistics
    ret = DeviceIoControl(hCJ, FSCTL_QUERY_USN_JOURNAL, 0, 0, ujd, Len(ujd), BytesReturned, olData)
    If ret = 0 Or BytesReturned <> Len(ujd) Then
        MsgBox WinAPIError
    Else
        BytesReturned = 0
        rujd.UsnJournalID = ujd.UsnJournalID
        rujd.StartUsn = ujd.FirstUsn
        rujd.ReasonMask = USN_MASK_ALL_REASONS ' Get every record
        'rujd.ReturnOnlyOnClose = False
        Do
            ' Get some records from the journal
            'ret = DeviceIoControl(hCJ, FSCTL_READ_USN_JOURNAL, rujd, Len(rujd), CJData, USN_PAGE_SIZE, BytesReturned, olData)
            ret = DeviceIoControlA(hCJ, FSCTL_READ_USN_JOURNAL, rujd, Len(rujd), dPtr, USN_PAGE_SIZE, BytesReturned, olData)
            If ret = 0 Or BytesReturned <= Len(rujd) Then
                Debug.Print WinAPIError()
                Exit Do
            End If
            Stop
        Loop While True
    End If
    ret = HeapFree(hHeap, 0, dPtr)
    CloseHandle hCJ
End Sub
 
Reply With Quote
 
New Member
Join Date: Oct 2005
Posts: 2
 
      21st Oct 2005
Solved it myself after leaving it for another couple of hours. Boolean's must only be 2 bytes long, making the input length incorrect but the error message focused my attention on what wasn't being returned when I should have been looking at what was sent to DeviceIoCtrl!
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
PHP's output buffer and ASP.NET's Response.OutputStream kellygreer1 Microsoft ASP .NET 3 12th Dec 2007 10:41 PM
How do I output zeros in access for null values =?Utf-8?B?Um9ja2V0TWFu?= Microsoft Access 5 28th Nov 2006 10:14 PM
flushing output buffer Neeraj Microsoft Dot NET Compact Framework 6 31st Oct 2003 07:14 AM
Output stream buffer size Rob Miller Microsoft Windows 2000 Developer 0 10th Jul 2003 01:27 AM
Output stream buffer size Rob Miller Microsoft Windows 2000 0 9th Jul 2003 07:40 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 07:57 PM.