sysinfo.as [WinNTデバイスドライバSysinfoモジュール]

;*******************************************************************************
; SysInfo Device Driver module Ver1.0a  [2007.09.23]
;  Programmed in HSP Ver3.1 ONION software (http://hsp.tv/)
;   Copyright (C) 2007 by abo, all rights reserved.
;*******************************************************************************

#ifdef __hsp30__
#ifndef __HSPSYSINFO__
#define global __HSPSYSINFO__

#define global STANDARD_RIGHTS_REQUIRED 0x000F0000
#define global GENERIC_READ 0x80000000
#define global GENERIC_WRITE    $40000000
#define global OPEN_EXISTING    3
#define global INVALID_HANDLE_VALUE 0xffffffff

#define global SERVICE_CONTROL_STOP 1
#define global SERVICE_CONTROL_PAUSE 2
#define global SERVICE_CONTROL_CONTINUE 3
#define global SERVICE_CONTROL_INTERROGATE 4
#define global SERVICE_CONTROL_SHUTDOWN 5
#define global SERVICE_CONTROL_PARAMCHANGE 6
#define global SERVICE_CONTROL_NETBINDADD 7
#define global SERVICE_CONTROL_NETBINDREMOVE 8
#define global SERVICE_CONTROL_NETBINDENABLE 9
#define global SERVICE_CONTROL_NETBINDDISABLE 10
#define global SERVICE_CONTROL_DEVICEEVENT 11
#define global SERVICE_CONTROL_HARDWAREPROFILECHANGE 12
#define global SERVICE_CONTROL_POWEREVENT 13
#define global SERVICE_CONTROL_SESSIONCHANGE 14

#define global SERVICE_QUERY_CONFIG 1
#define global SERVICE_CHANGE_CONFIG 2
#define global SERVICE_QUERY_STATUS 4
#define global SERVICE_ENUMERATE_DEPENDENTS 8
#define global SERVICE_START 16
#define global SERVICE_STOP 32
#define global SERVICE_PAUSE_CONTINUE 64
#define global SERVICE_INTERROGATE 128
#define global SERVICE_USER_DEFINED_CONTROL 256
#const  global SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL)

#define global SERVICE_WIN32_OWN_PROCESS    16
#define global SERVICE_WIN32_SHARE_PROCESS  32
#define global SERVICE_KERNEL_DRIVER    1
#define global SERVICE_FILE_SYSTEM_DRIVER   2
#define global SERVICE_INTERACTIVE_PROCESS  256
#define global SERVICE_BOOT_START   0
#define global SERVICE_SYSTEM_START 1
#define global SERVICE_AUTO_START   2
#define global SERVICE_DEMAND_START 3
#define global SERVICE_DISABLED 4
#define global SERVICE_ERROR_IGNORE 0
#define global SERVICE_ERROR_NORMAL 1
#define global SERVICE_ERROR_SEVERE 2
#define global SERVICE_ERROR_CRITICAL   3

#define global DELETE_MARK  0x10000

/* wOStype : Windows OS Descriptor */
#define global OS_UNKNOWN   0   /* Unknown Windows  */
#define global Windows9X    1   /* Windows 95/98/Me */
#define global WindowsNT    2   /* Windows NT/2000/XP */

/* 
 * To use SysInfo, just call StartSysInfo first and 
 * StopSysInfo last from user functions. 
 * * After call StartSysInfo, just check return value.
 * bit0(mask with 0x0001) is not zero, this means 
 * start process could not initialize SysInfo 
 * manager, so you cannot access any I/O port, 
 * please quit program. Else you can use SysInfo.
 * * There is no problem calling StartSysInfo/StopSysInfo
 * under Windows95/98/Me.
 */

#module "hspsysinfo"

/* wSysInfoflag : Result Status of StartSysInfo */
#define global SYSINFO_NOERR   (0x00)  /* SysInfo : No Error Detected */
#define global SYSINFO_ERROR   (0x01)  /* SysInfo : Error Detected*/
#define global SYSINFO_OPEN    (0x02)  /* SysInfo : Opened  */
#define global SYSINFO_START   (0x04)  /* SysInfo : Started */
#define global SYSINFO_INSTALL (0x08)  /* SysInfo : Installed */
#define global SYSINFO_INVOS   (0x10)  /* SysInfo : GetVersionEx() Error */

#deffunc _InitSysInfo int X64

/* SysInfo CTL Names for WindowsNT/2000/XP */
    SYSINFO_dname="\\\\.\\CrystalSysInfo"; /* Device Name     */
    if X64 {
        SYSINFO_fname="SysInfoX64.sys"
    } else {
        SYSINFO_fname="SysInfo.sys";    /* Driver Filename */
        ;   ****************************************************************************
        xdim fnIo_inp9x,4   ;io_inp
        asm fnIo_inp9x,{"
            ORG     0
            MOV     DX,[ESP+04]     ; DX <- p1
            IN      AL,DX           ; AL <- DX
            AND     EAX,0xFF        ; EAX <- EAX&0xFF
            RET
            END
        "}
        ;   ****************************************************************************
        xdim fnIo_inpw9x,4  ;io_inpw
        asm fnIo_inpw9x,{"
            ORG     0
            MOV     DX,[ESP+04]     ; DX <- p1
            IN      AX,DX           ; AX <- DX
            AND     EAX,0xFFFF      ; EAX <- EAX&0xFFFF
            RET
            END
        "}
        ;   ****************************************************************************
        xdim fnIo_inpd9x,4  ;io_inpd
        asm fnIo_inpd9x,{"
            ORG     0
            MOV     DX,[ESP+04]     ; DX <- p1
            IN      EAX,DX          ; EAX <- DX
            RET
            END
        "}
        ;   ****************************************************************************
        xdim fnIo_out9x,4   ;io_out
        asm fnIo_out9x,{"
            ORG     0
            MOV     DX,[ESP+04]     ; DX <- p1
            MOV     AL,[ESP+08]     ; AL <- p2
            OUT     DX,AL           ; DX <- AL
            RET
            END
        "}
        ;   ****************************************************************************
        xdim fnIo_outw9x,4  ;io_outw
        asm fnIo_outw9x,{"
            ORG     0
            MOV     DX,[ESP+04]     ; DX <- p1
            MOV     AX,[ESP+08]     ; AX <- p2
            OUT     DX,AX           ; DX <- AX
            RET
            END
        "}
        ;   ****************************************************************************
        xdim fnIo_outd9x,4  ;io_outd
        asm fnIo_outd9x,{"
            ORG     0
            MOV     DX,[ESP+04]     ; DX <- p1
            MOV     EAX,[ESP+08]    ; EAX <- p2
            OUT     DX,EAX          ; DX <- EAX
            RET
            END
        "}
        ;   ****************************************************************************
    }
    SYSINFO_sname="CrystalSysInfo";        /* Service Name    */

/* SysInfo Device Full Path Filename */
    sdim szFullPath,MAX_PATH;

/*  Service Control Manager Handler */
    hSCM = NULL;

/* SERVICE_STATUS構造体 */
    dim svc_status,8
;   Type SERVICE_STATUS
;    dwServiceType As Long
;    dwCurrentState As Long
;    dwControlsAccepted As Long
;    dwWin32ExitCode As Long
;    dwServiceSpecificExitCode As Long
;    dwCheckPoint As Long
;    dwWaitHint As Long
;   End Type

    data=0 : ReturnedLength=0
    dim prm,3

    return

/**-----------------------------------------------------**/
/* Distinguish Windows OS-Type, */ 
/* for SysInfo CTL is necessary or not. */
; sysinfo(0)
;   Windows95     "Windows9X ver4.0"
;   Windows98     "Windows9X ver4.10"
;   WindowsMe     "Windows9X ver4.90"
;   WindowsNT3.x  "WindowsNT ver3. "
;   WindowsNT4.0  "WindowsNT ver4.0"
;   Windows2000   "WindowsNT ver5.0"
;   WindowsXP     "WindowsNT ver5.1"
;   Windows2003   "WindowsNT ver5.2"
#defcfunc OsType
    OSinfo=sysinfo_os
    return CND(strmid(OSinfo,0,9)="Windows9X",Windows9X,CND(strmid(OSinfo,0,9)="WindowsNT",WindowsNT,OS_UNKNOWN))

/* Open Service Control Manager */
/* Returns : 0 = OK */
/*        else = NG */
#deffunc OpenSCM
    if hSCM == NULL {
        hSCM = _OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)
        if hSCM == NULL : return _GetLastError(); // Error
    }
    return SYSINFO_NOERR; // OK

/* Close Service Control Manager */
#deffunc CloseSCM
    if hSCM != NULL {
        CloseServiceHandle hSCM;
    }
    hSCM = NULL;
    wSYSINFOflag = wSYSINFOflag & NOTB(SYSINFO_INSTALL)
    return;

/**-----------------------------------------------------**/
/* SysInfo Driver Start */
/* Returns : 0 = OK */
/*        else = NG */
#deffunc DriverStart var szDriver
    status = 0;
    hSvc = NULL;

    /* Open Service Control Manager */
    OpenSCM : if stat : return SYSINFO_ERROR

    /* SysInfo Open Service */
    hSvc = _OpenService(hSCM, varptr(szDriver), SERVICE_ALL_ACCESS)
    if hSvc != NULL {
        StartService hSvc, 0, NULL
        if stat == 0 { // Error
            status = _GetLastError();
        }
        else {; // OK
        }
    }
    else {
        status = _GetLastError(); // Error
    }
    if hSvc != NULL : CloseServiceHandle hSvc;

    return status;

/**-----------------------------------------------------**/
/* SysInfo Driver Stop */
/* Returns : 0 = OK */
/*        else = NG */
#deffunc DriverStop var szDriver

    status = 0;
    hSvc = NULL;

    /* Open Service Control Manager */
    OpenSCM : if stat : return SYSINFO_ERROR

    /* Check if Service available or not */
    hSvc = _OpenService(hSCM, varptr(szDriver), SERVICE_ALL_ACCESS)
    if hSvc != NULL {
        ControlService hSvc, SERVICE_CONTROL_STOP, varptr(svc_status)
        if stat == 0 { // Error
            status = _GetLastError();
        }
        else {; // OK
        }
    }
    else {
        status = _GetLastError(); // Error
    }
    if hSvc != NULL : CloseServiceHandle hSvc;

    wSYSINFOflag = wSYSINFOflag & NOTB(SYSINFO_START);
    return status;

/**-----------------------------------------------------**/
/* SysInfo Driver Delete */
/* Returns : 0 = OK */
/*        else = NG */
#deffunc DriverDelete var szDriver

    status = 0;
    hSvc = NULL;

    /* Open Service Control Manager */
    OpenSCM : if stat : return SYSINFO_ERROR

    /* Put Delete Mark to  Service Control Database */ 
    hSvc = _CreateService(hSCM, varptr(szDriver), varptr(szDriver), DELETE_MARK, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, varptr(szFullPath), NULL, NULL, NULL, NULL, NULL);

    /* Check if Service available or not */
    hSvc = _OpenService(hSCM, varptr(szDriver), SERVICE_ALL_ACCESS)
    if hSvc != NULL {
        DeleteService hSvc
        if stat == 0 { // Error
            status = _GetLastError();
        }
        else {; // OK
        }
    }
    else {
        status = _GetLastError(); // Error
    }
    if hSvc != NULL : CloseServiceHandle hSvc;

    wSYSINFOflag = wSYSINFOflag & NOTB(SYSINFO_OPEN);
    return status;

/**-----------------------------------------------------**/
/* SysInfo Install */
/* stat : 0 = OK */
/*        else = NG */
#deffunc DriverInstall var szFname, var szDriver

    status = 0;
    hSvc = NULL;

    /* Open Service Control Manager */
    OpenSCM : if stat : return SYSINFO_ERROR; // Error

    /* Get SYSINFO Device Full Path Filename */
    SearchPath NULL, varptr(szFname), NULL, MAX_PATH, varptr(szFullPath), varptr(filename)

    /* Registers to  Service Control Database */ 
    hSvc = _CreateService(hSCM, varptr(szDriver), varptr(szDriver), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, varptr(szFullPath), NULL, NULL, NULL, NULL, NULL)
    if hsvc == NULL {
        status=_GetLastError(); // Error
        if (status == 1073) { ; Service Already Exists, then Stop & Delete
            DriverStop SYSINFO_sname;
            DriverDelete SYSINFO_sname;
        }
    } 
    else {
        CloseServiceHandle hSvc; // OK
        wSYSINFOflag = wSYSINFOflag & NOTB(SYSINFO_INSTALL);
    }
    return status

/**-----------------------------------------------------**/
/* SysInfo Stop Process */
#deffunc StopSysInfo

    /* No Operation if OS is Win95/98/Me */
    wOStype=OsType()
    if wOStype == Windows9X : return SYSINFO_NOERR;

    if h != INVALID_HANDLE_VALUE { // OK(Opened)
        CloseHandle h;
    }

    if wSYSINFOflag & SYSINFO_START { // Started ?
        DriverStop SYSINFO_sname
        if stat : return (wSYSINFOflag & SYSINFO_START); // Error
    }
    if wSYSINFOflag & SYSINFO_INSTALL { // Installed ?
        DriverDelete SYSINFO_sname
        if stat : return (wSYSINFOflag & SYSINFO_INSTALL); // Error
    }

    CloseSCM;

    return SYSINFO_NOERR;

/**-----------------------------------------------------**/
/* SysInfo Start Process */
/* Returns : bit0 = Error Detected */
/*           bit1 = Device Opened */
/*           bit2 = Device Started */
/*           bit3 = Device Installed */
#deffunc StartSysInfo

    /* Init Ret val */
    wSYSINFOflag = 0;

    /* Exit if Windows OS Type is Win95/98/Me */
    wOStype=OsType()
    if wOStype == Windows9X : return wSYSINFOflag; // OK, No need to CTL SysInfo
    if wOStype != WindowsNT {
        wSYSINFOflag = wSYSINFOflag | SYSINFO_ERROR | SYSINFO_INVOS;
        return wSYSINFOflag; // NG, No need to CTL SysInfo
    }

    /* WinNT , try SysInfo */
    i = 0
    while i<3 : i++
        if i>=3 { // Device Install
            DriverInstall SYSINFO_fname, SYSINFO_sname
            if stat { 
                _break; // no retry
            }
            else {
                wSYSINFOflag = wSYSINFOflag | SYSINFO_INSTALL; // OK(Installed)
            }
        }
        if i>=2 { // Device Start
            DriverStart SYSINFO_sname
            if stat {
                _continue; // retry with install
            }
            else {
                wSYSINFOflag = wSYSINFOflag | SYSINFO_START; // OK(Started)
            }
        }

        // Device Open
        h = _CreateFile(varptr(SYSINFO_dname), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
        if h != INVALID_HANDLE_VALUE { // OK(Opened)
            StartService h, 0, NULL
            CloseServiceHandle h;
            wSYSINFOflag = (wSYSINFOflag|SYSINFO_OPEN|SYSINFO_START|SYSINFO_INSTALL)
            return wSYSINFOflag; // OK return
        }
        else { _continue }; // Error

    wend

    StopSysInfo;
    wSYSINFOflag = wSYSINFOflag | SYSINFO_ERROR; // Error
    return wSYSINFOflag; // NG Return
    
#defcfunc io_inp9x int adr
    prm=adr : return callfunc(prm,varptr(fnIo_inp9x),1)
#defcfunc io_inpw9x int adr
    prm=adr : return callfunc(prm,varptr(fnIo_inpw9x),1)
#defcfunc io_inpd9x int adr
    prm=adr : return callfunc(prm,varptr(fnIo_inpd9x),1)
#deffunc io_out9x int adr, int dt
    prm=adr,dt : res=callfunc(prm,varptr(fnIo_out9x),2) : return
#deffunc io_outw9x int adr, int dt
    prm=adr,dt : res=callfunc(prm, varptr(fnIo_outw9x),2) : return
#deffunc io_outd9x int adr, int dt
    prm=adr,dt : res=callfunc(prm,varptr(fnIo_outd9x),2) : return

#define PCI_TYPE 40000
#define METHOD_BUFFERED 0
#define METHOD_IN_DIRECT 1
#define METHOD_OUT_DIRECT 2
#define METHOD_NEITHER 3
#define FILE_ANY_ACCESS 0
#define FILE_READ_ACCESS 1
#define FILE_WRITE_ACCESS 2

#define IOCTL_PCI_READ_PORT_UCHAR ((PCI_TYPE<<16)|(FILE_READ_ACCESS<<14)|(0x900<<2)|(METHOD_BUFFERED))
#define IOCTL_PCI_READ_PORT_USHORT ((PCI_TYPE<<16)|(FILE_READ_ACCESS<<14)|(0x901<<2)|(METHOD_BUFFERED))
#define IOCTL_PCI_READ_PORT_ULONG (PCI_TYPE<<16)|(FILE_READ_ACCESS<<14)|(0x902<<2)|(METHOD_BUFFERED)
#define IOCTL_PCI_WRITE_PORT_UCHAR ((PCI_TYPE<<16)|(FILE_WRITE_ACCESS<<14)|(0x910<<2)|(METHOD_BUFFERED))
#define IOCTL_PCI_WRITE_PORT_USHORT ((PCI_TYPE<<16)|(FILE_WRITE_ACCESS<<14)|(0x911<<2)|(METHOD_BUFFERED))
#define IOCTL_PCI_WRITE_PORT_ULONG (PCI_TYPE<<16)|(FILE_WRITE_ACCESS<<14)|(0x912<<2)|(METHOD_BUFFERED)

#define IOCTL_PCI_READ_MEM ((PCI_TYPE<<16)|(FILE_READ_ACCESS<<14)|(0x920<<2)|(METHOD_BUFFERED))
#define IOCTL_PCI_WRITE_MEM ((PCI_TYPE<<16)|(FILE_WRITE_ACCESS<<14)|(0x930<<2)|(METHOD_BUFFERED))

#define IOCTL_PCI_READ_CONF ((PCI_TYPE<<16)|(FILE_READ_ACCESS<<14)|(0x940<<2)|(METHOD_BUFFERED))
#define IOCTL_PCI_WRITE_CONF ((PCI_TYPE<<16)|(FILE_WRITE_ACCESS<<14)|(0x950<<2)|(METHOD_BUFFERED))

/**-----------------------------------------------------**/

/* I/O Read Long */
/* stat : data   */

#defcfunc Io_inpd int p1
    switch wOStype
    case WindowsNT
        IoAddress=p1 : DeviceIoControl h, IOCTL_PCI_READ_PORT_ULONGvarptr(IoAddress), 4, varptr(data), 4, varptr(ReturnedLength), NULL;
        swbreak
    case Windows9X
        data=io_inpd9x(p1)
        swbreak
    default
        data=0
        swbreak
    swend
    return data;

/**-----------------------------------------------------**/

/* I/O Read Char */
/* stat : data   */

#defcfunc Io_inpw int p1
    switch wOStype
    case WindowsNT
        IoAddress=p1 : DeviceIoControl h, IOCTL_PCI_READ_PORT_USHORTvarptr(IoAddress), 4, varptr(data), 2, varptr(ReturnedLength), NULL;
        swbreak
    case Windows9X
        data=io_inpw9x(p1)
        swbreak
    default
        data=0
        swbreak
    swend
    return data&0xFFFF;

/**-----------------------------------------------------**/

/* I/O Read Char */
/* stat : data   */

#defcfunc Io_inp int p1
    switch wOStype
    case WindowsNT
        IoAddress=p1 : DeviceIoControl h, IOCTL_PCI_READ_PORT_UCHARvarptr(IoAddress), 4, varptr(data), 1, varptr(ReturnedLength), NULL;
        swbreak
    case Windows9X
        data=io_inp9x(p1)
        swbreak
    default
        data=0
        swbreak
    swend
    return data&0xFF;

/* I/O Write Long */
/* stat : data   */

#deffunc io_outd int p1, int p2
    switch wOStype
    case WindowsNT
        prm=p1,p2 : DeviceIoControl h, IOCTL_PCI_WRITE_PORT_ULONGvarptr(prm), 8, NULL, 0, varptr(ReturnedLength), NULL;
        swbreak
    case Windows9X
        io_outd9x p1,p2
        swbreak
    swend
    return;

#deffunc io_outw int p1, int p2
    switch wOStype
    case WindowsNT
        prm=p1,p2 : DeviceIoControl h, IOCTL_PCI_WRITE_PORT_USHORTvarptr(prm), 6, NULL, 0, varptr(ReturnedLength), NULL;
        swbreak
    case Windows9X
        io_outw9x p1,p2
        swbreak
    swend
    return;

#deffunc io_out int p1, int p2
    switch wOStype
    case WindowsNT
        prm=p1,p2 : DeviceIoControl h, IOCTL_PCI_WRITE_PORT_UCHARvarptr(prm), 5, NULL, 0, varptr(ReturnedLength), NULL;
        swbreak
    case Windows9X
        io_out9x p1,p2
        swbreak
    swend
    return;

#defcfunc Mem_readd int p1
    switch wOStype
    case WindowsNT
        prm=p1,4,1 : DeviceIoControl h, IOCTL_PCI_READ_MEMvarptr(prm), 12, varptr(data), 4, varptr(ReturnedLength), NULL;
        swbreak
    default
        data=0
        swbreak
    swend
    return data;

#defcfunc Mem_readw int p1
    switch wOStype
    case WindowsNT
        prm=p1,2,1 : DeviceIoControl h, IOCTL_PCI_READ_MEMvarptr(prm), 12, varptr(data), 4, varptr(ReturnedLength), NULL;
        swbreak
    default
        data=0
        swbreak
    swend
    return data&0xFFFF;

#defcfunc Mem_read int p1
    switch wOStype
    case WindowsNT
        prm=p1,1,1 : DeviceIoControl h, IOCTL_PCI_READ_MEMvarptr(prm), 12, varptr(data), 4, varptr(ReturnedLength), NULL;
        swbreak
    default
        data=0
        swbreak
    swend
    return data&0xFF;

#global

    _InitSysInfo 0

#endif   ;__SYSINFO__
#endif   ;__hsp30__

// End of SysInfo.as