Imports System.Collections.Generic
Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Public Class Form1

    Public Sub New()        
        InitializeComponent()

        BoxedAppSDK.NativeMethods.BoxedAppSDK_Init()
    End Sub

    Private Sub btnOpenAndWrite_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenAndWrite.Click
        Try
            System.IO.File.WriteAllText("1.txt", "some data...")
            MessageBox.Show("Some data added to file 1.txt")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub chkHook_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkHook.CheckedChanged
        If chkHook.Checked Then
            SetHook()
        Else
            RemoveHook()
        End If
    End Sub

    Private hookCreateFileW As IntPtr = IntPtr.Zero

    Private Sub SetHook()
        If hookCreateFileW <> IntPtr.Zero Then Exit Sub

        pCreateFileW = GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateFileW")

        hookCreateFileW = BoxedAppSDK.NativeMethods.BoxedAppSDK_HookFunction(pCreateFileW, New TCreateFile(AddressOf My_CreateFileW), True)

        pCreateFileW = DirectCast(BoxedAppSDK.NativeMethods.BoxedAppSDK_GetOriginalFunction(hookCreateFileW, GetType(TCreateFile)), TCreateFile)
    End Sub

    Private Sub RemoveHook()
        If hookCreateFileW = IntPtr.Zero Then Exit Sub
        BoxedAppSDK.NativeMethods.BoxedAppSDK_UnhookFunction(hookCreateFileW)
        hookCreateFileW = IntPtr.Zero
    End Sub

    Private Declare Ansi Function GetProcAddress Lib "kernel32" (ByVal hModule As IntPtr, ByVal procName As String) As TCreateFile

    <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
    End Function

    <DllImport("kernel32.dll")> _
    Private Shared Sub SetLastError(ByVal dwErrCode As UInteger)
    End Sub

    Public Const ERROR_FILE_NOT_FOUND As Int32 = 2

    Public Delegate Function TCreateFile(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpFileName As String, <MarshalAs(UnmanagedType.U4)> ByVal dwDesiredAccess As Integer, <MarshalAs(UnmanagedType.U4)> ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal dwCreationDisposition As Integer, <MarshalAs(UnmanagedType.U4)> ByVal dwFlagsAndAttributes As Integer, _
    ByVal hTemplateFile As IntPtr) As UInteger

    Shared pCreateFileW As TCreateFile = Nothing

    Private Shared Function My_CreateFileW(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpFileName As String, <MarshalAs(UnmanagedType.U4)> ByVal dwDesiredAccess As Integer, <MarshalAs(UnmanagedType.U4)> ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal dwCreationDisposition As Integer, <MarshalAs(UnmanagedType.U4)> ByVal dwFlagsAndAttributes As Integer, _
                                            ByVal hTemplateFile As IntPtr) As UInteger
        If lpFileName.Contains("\1.txt") Then
            SetLastError(ERROR_FILE_NOT_FOUND)
            Return &HFFFFFFFFUI
        End If

        Return pCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
    End Function
End Class
