Attribute VB_Name = "modAcpiECPatch"
' ----------------------------------------------------------------------------
'  Copyright (C) 2009 Noda (Yohan Lasorsa) - http://nodadev.wordpress.com
' ----------------------------------------------------------------------------
'  This software Is provided 'as-is', without any express or implied
'  warranty. In no event will the author be held liable for any damages
'  arising from the use of this software.
'
'  Permission is granted to anyone to use this software for any purpose,
'  including commercial applications, and to alter it and redistribute it
'  freely, subject to the following restrictions:
'
'  1. The origin of this software must not be misrepresented; you must not
'     claim that you wrote the original software. If you use this software
'     in a product, an acknowledgment in the product documentation would be
'     appreciated but is not required.
'  2. Altered source versions must be plainly marked as such, and must not be
'     misrepresented as being the original software.
'  3. This notice may not be removed or altered from any source distribution.
' ----------------------------------------------------------------------------

Option Explicit

Private Const ACPIEC_REG_PATH As String = "SYSTEM\ControlSet001\Services\ACPIEC"
Private Const ACPIEC_SYS_PATH As String = "system32\DRIVERS\"
Private Const ACPIEC_KEY_NAME As String = "ImagePath"
Private Const ACPIEC_ORIGINAL_FILE As String = "acpiec.sys"
Private Const ACPIEC_PATCHED_FILE As String = "acpiec_nolog.sys"
Private Const ACPIEC_ORIGINAL_DATA As String = "IoWriteErrorLogEntry"
Private Const ACPIEC_PATCHED_DATA As String = "IoFreeErrorLogEntry"
Private Const RESTART_MSG As String = "You must restart your computer to make the changes take effect!"

Public Function CheckACPIECPatched() As Boolean
    If (RegDoesKeyExist(HKEY_LOCAL_MACHINE, ACPIEC_REG_PATH)) Then
        If (InStr(CStr(RegQueryKey(HKEY_LOCAL_MACHINE, ACPIEC_REG_PATH, ACPIEC_KEY_NAME)), "nolog") <> 0) Then
            CheckACPIECPatched = True
        Else
            CheckACPIECPatched = False
        End If
    End If
End Function

Public Sub PatchACPIEC()
    Dim f As Long
    Dim data As String

    On Error GoTo patch_error
    
    ' patch file
    data = Space$(FileLen(GetWindowsPath & "\" & ACPIEC_SYS_PATH & ACPIEC_ORIGINAL_FILE))
    
    f = FreeFile()
    Open (GetWindowsPath & "\" & ACPIEC_SYS_PATH & ACPIEC_ORIGINAL_FILE) For Binary As #f
    Get #f, , data
    Close #f
    
    If InStr(data, ACPIEC_ORIGINAL_DATA) <> 0 Then
        data = Replace(data, ACPIEC_ORIGINAL_DATA, ACPIEC_PATCHED_DATA + Chr(0))
        Open (GetWindowsPath & "\" & ACPIEC_SYS_PATH & ACPIEC_PATCHED_FILE) For Binary As #f
        Put #f, , data
        Close #f
        
        ' patch registry
        If (RegDoesKeyExist(HKEY_LOCAL_MACHINE, ACPIEC_REG_PATH)) Then
            RegCreateKeyValue HKEY_LOCAL_MACHINE, ACPIEC_REG_PATH, ACPIEC_KEY_NAME, ACPIEC_SYS_PATH & ACPIEC_PATCHED_FILE
        End If
        
        MsgBox RESTART_MSG
    Else
        GoTo patch_error
    End If
    Exit Sub
    
patch_error:
    MsgBox "Unexpected error, can't patch acpiec.sys"
End Sub

Public Sub UnpatchACPIEC()
    ' unpatch registry
    If (RegDoesKeyExist(HKEY_LOCAL_MACHINE, ACPIEC_REG_PATH)) Then
        RegCreateKeyValue HKEY_LOCAL_MACHINE, ACPIEC_REG_PATH, ACPIEC_KEY_NAME, ACPIEC_SYS_PATH & ACPIEC_ORIGINAL_FILE
    End If
    MsgBox RESTART_MSG
End Sub
