zoukankan      html  css  js  c++  java
  • Delphi调用安装驱动sys的单元

    unit SysDriver;
    
    interface
    
    uses windows, winsvc; // jwawinsvc;
    
    Type
      TSysDriver = class(TObject)
      private
        HomeDir, DriverDir, DriverName, DEVICE_NAME_STRING,
        DriverPath      : string; // the whole thing
        hSCMan          : SC_HANDLE; // Service Control Manager
        hDevice         : SC_HANDLE; // Handle for device
      public
        HaveLoad        : Boolean;
        BaseControlCode : DWORD;
        constructor Create(DeviceName: string);
    
        //---------------------------------------
        // Interact with Service Control Manager
        //---------------------------------------
        function OpenSCM: DWORD;
        function CloseSCM: DWORD;
    
        //---------------------------------------
        // Install/Start/Stop/Remove driver
        //---------------------------------------
        function Install(newdriverpath: string): DWORD; { use '' for default }
        function Start:   DWORD;
        function Stop:    DWORD;
        function Remove:  DWORD;
    
        //--------------------------------
        // Device Open/Close
        //--------------------------------
        function DeviceOpen: DWORD;   // get a valid hDevice
        function DeviceClose: DWORD;
    
        //--------------------------------
        function IOControl(Cmd: DWORD; inBuf: Pointer; inSize: DWORD;
          outbuf: Pointer; var outSize: DWORD): Boolean;
        //--------------------------------
        function ErrorLookup(ErrorNum: DWORD): string;
      end;
    
    //-------------------------------------------
    implementation
    //-------------------------------------------
    uses sysutils;
    
    Const // from ntddk
    // Service Types (Bit Mask)
      SERVICE_KERNEL_DRIVER        =  $00000001;
      SERVICE_FILE_SYSTEM_DRIVER   =  $00000002;
      SERVICE_ADAPTER              =  $00000004;
      SERVICE_RECOGNIZER_DRIVER    =  $00000008;
    
      SERVICE_DRIVER               =  SERVICE_KERNEL_DRIVER or
                                      SERVICE_FILE_SYSTEM_DRIVER or
                                      SERVICE_RECOGNIZER_DRIVER;
    
      SERVICE_WIN32_OWN_PROCESS    =  $00000010;
      SERVICE_WIN32_SHARE_PROCESS  =  $00000020;
      SERVICE_WIN32                =  SERVICE_WIN32_OWN_PROCESS or
                                      SERVICE_WIN32_SHARE_PROCESS;
    
      SERVICE_INTERACTIVE_PROCESS  =  $00000100;
    
      SERVICE_TYPE_ALL             =  SERVICE_WIN32   or
                                      SERVICE_ADAPTER or
                                      SERVICE_DRIVER  or
                                      SERVICE_INTERACTIVE_PROCESS;
    // Start Type
      SERVICE_BOOT_START           =  $00000000;
      SERVICE_SYSTEM_START         =  $00000001;
      SERVICE_AUTO_START           =  $00000002;
      SERVICE_DEMAND_START         =  $00000003;
      SERVICE_DISABLED             =  $00000004;
    
    // Error control type
      SERVICE_ERROR_IGNORE         =  $00000000;
      SERVICE_ERROR_NORMAL         =  $00000001;
      SERVICE_ERROR_SEVERE         =  $00000002;
      SERVICE_ERROR_CRITICAL       =  $00000003;
    
    Type
      TErrorMsg = record
        Num: DWORD;
        Msg: string;
      end;
    
    Const
      ErrorMsgCt = 30;
      ERROR_SCM_CANT_CONNECT = 9998;
      ERROR_NO_DEVICE_HANDLE = 9997;
      ERROR_GW_BUFFER_TOO_SMALL = 9997;
      ERROR_UNEXPECTED = 9999;
    
      ErrorMsgs: array[1..ErrorMsgCt] of TErrorMsg = (
        (Num: ERROR_SUCCESS                   ; Msg: 'Operation was successful'),
        (Num: ERROR_INVALID_FUNCTION          ; Msg: 'Invalid Function'),
        (Num: ERROR_ACCESS_DENIED             ; Msg: 'Access denied'),
        (Num: ERROR_CIRCULAR_DEPENDENCY       ; Msg: 'Circular dependency'),
        (Num: ERROR_DATABASE_DOES_NOT_EXIST   ; Msg: 'Database doesn''t exist'),
        (Num: ERROR_DEPENDENT_SERVICES_RUNNING; Msg: 'Dependent services running'),
        (Num: ERROR_DUP_NAME                  ; Msg: 'Display name already exists'),
        (Num: ERROR_INVALID_HANDLE            ; Msg: 'Invalid handle'),
        (Num: ERROR_INVALID_NAME              ; Msg: 'Invalid service name'),
        (Num: ERROR_INVALID_PARAMETER         ; Msg: 'Invalid Parameter'),
        (Num: ERROR_INVALID_SERVICE_ACCOUNT   ; Msg: 'User account doesn''t exist'),
        (Num: ERROR_INVALID_SERVICE_CONTROL   ; Msg: 'Invalid service control code'),
        (Num: ERROR_PATH_NOT_FOUND            ; Msg: 'Path not found'),
        (Num: ERROR_SERVICE_ALREADY_RUNNING   ; Msg: 'Service already running'),
        (Num: ERROR_SERVICE_CANNOT_ACCEPT_CTRL; Msg: 'Service can''t accept control'),
        (Num: ERROR_SERVICE_DATABASE_LOCKED   ; Msg: 'The database is locked'),
        (Num: ERROR_SERVICE_DEPENDENCY_DeleteD; Msg: 'Depends on nonexistant service'),
        (Num: ERROR_SERVICE_DEPENDENCY_FAIL   ; Msg: 'Depends on service that failed'),
        (Num: ERROR_SERVICE_DISABLED          ; Msg: 'Service has been disabled'),
        (Num: ERROR_SERVICE_DOES_NOT_EXIST    ; Msg: 'Service doesn''t exist'),
        (Num: ERROR_SERVICE_EXISTS            ; Msg: 'Service already exists'),
        (Num: ERROR_SERVICE_LOGON_FAILED      ; Msg: 'Service couldn''t be logged on'),
        (Num: ERROR_SERVICE_MARKED_FOR_Delete ; Msg: 'Service marked for deletion'),
        (Num: ERROR_SERVICE_NO_THREAD         ; Msg: 'Couldn''t create thread'),
        (Num: ERROR_SERVICE_NOT_ACTIVE        ; Msg: 'Service hasn''t been started'),
        (Num: ERROR_SERVICE_REQUEST_TIMEOUT   ; Msg: 'Service timed out'),
        (Num: ERROR_GW_BUFFER_TOO_SMALL       ; Msg: 'Buffer too small'),
        (Num: ERROR_NO_DEVICE_HANDLE          ; Msg: 'No device handle'),
        (Num: ERROR_SCM_CANT_CONNECT          ; Msg: 'Can''t connect to Service Control Manager'),
        (Num: ERROR_UNEXPECTED                ; Msg: 'An unexpected error occured')
      );
    
    //-----------------------------------------
    function TSysDriver.ErrorLookup(ErrorNum: DWORD): string;
    //-----------------------------------------
    Var
      N: integer;
    Begin
      If Error <> ERROR_SUCCESS then
       begin
        result := 'Error: ' + IntToStr(ErrorNum) + ': ';
        exit;
       end;
        
      For N := 1 to ErrorMsgCt do
      Begin
        if ErrorNum = ErrorMsgs[N].Num then
        Begin
          break;
        end;
      end;
    result:=ErrorMsgs[N].Msg;
    
    end;
    
    //----------------------------------------------------------
    // IOCTL codes
    //----------------------------------------------------------
    function CTL_CODE(DeviceType: integer; func: integer; meth: integer; access: integer): DWORD;
    Begin
      result := (DeviceType shl 16) or (Access shl 14) or (func shl 2) or (meth);
    end;
    
    Const
      // Buffering method for user-mode app talking to drive
      METHOD_BUFFERED    = 0;
      METHOD_IN_DIRECT   = 1;
      METHOD_OUT_DIRECT  = 2;
      METHOD_NEITHER     = 3;
    
      // Define the access allowed
      FILE_ANY_ACCESS    = 0;
      FILE_READ_ACCESS   = 1;     // file & pipe
      FILE_WRITE_ACCESS  = 2;     // file & pipe
    
    
    //-----------------------------------------
    constructor TSysDriver.Create(DeviceName: string);
    //-----------------------------------------
    Begin
      hSCMan  := 0;
      hDevice := INVALID_HANDLE_VALUE;
      HomeDir := ExtractFilePath(GetModuleName(HInstance));
      DEVICE_NAME_STRING := DeviceName;
      DriverName  := DEVICE_NAME_STRING;
      HaveLoad    :=False;
        // default driver name needed by stop/remove if install wasn't executed
        // this run (ie: driver already installed
    end;
    
    //-------------------------------------------
    function TSysDriver.OpenSCM:  DWORD;
    //-------------------------------------------
    Begin
      result := ERROR_SUCCESS;
      hSCMan := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
      if hSCMan = 0 then result := ERROR_SCM_CANT_CONNECT;
    end;
    
    //-------------------------------------------
    function TSysDriver.CloseSCM:  DWORD;
    //-------------------------------------------
    Begin
      result := ERROR_SUCCESS;
      CloseServiceHandle(hSCMan);
      hSCMan := 0;
    end;
    
    //-----------------------------------------
    function TSysDriver.Install(newdriverpath: string): DWORD; { use '' for default }
    //-----------------------------------------
    Var
      hService: SC_HANDLE;
      dwStatus: DWORD;
    Begin
      dwStatus := 0;
    
      If newdriverpath = '' then
      Begin
        DriverDir   := HomeDir;
        DriverName  := DEVICE_NAME_STRING;
      end else
      Begin
        DriverDir  := ExtractFilePath(newdriverpath);
       // DriverName := ExtractFileName(driverpath);
      end;
      DriverPath  := DriverDir + DriverName+'.sys';
    
       // add to service control manager's database
       hService := CreateService(hSCMan, PChar(DriverName),PChar(DriverName),
                  SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
                  SERVICE_ERROR_NORMAL, PChar(DriverPath),
                  nil, nil, nil, nil, nil);
       if (hService = 0) then
       Begin
         dwStatus := GetLastError();
       end else
       Begin
         CloseServiceHandle(hService);
       end;
    
       result := dwStatus;
    end;
    
    //-------------------------------------------
    function TSysDriver.Start:   DWORD;
    //-------------------------------------------
    Var
      hService: SC_HANDLE;
      dwStatus: DWORD;
      lpServiceArgVectors: PChar;
      temp: LongBool;
    Begin
      dwStatus := 0;
      lpServiceArgVectors := nil;
    
       // get a handle to the service
       hService := OpenService(hSCMan, PChar(DriverName), SERVICE_ALL_ACCESS);
       if hService <> 0 then
       Begin
          // start the driver
          temp := StartService(hService, 0, PChar(lpServiceArgVectors));
          if not temp then dwStatus := GetLastError();
       end else dwStatus := GetLastError();
    
       if (hService <> 0) then CloseServiceHandle(hService);
       result := dwStatus;
    end;
    
    //-------------------------------------------
    function TSysDriver.Stop:    DWORD;
    //-------------------------------------------
    Var
      hService: SC_HANDLE;
      dwStatus: DWORD;
      serviceStatus: TServiceStatus;
      temp: LongBool;
    Begin
      dwStatus := 0;
    
      // get a handle to the service
      hService := OpenService(hSCMan, PChar(DriverName), SERVICE_ALL_ACCESS);
      if hService <> 0 then
      Begin
         // stop the driver
         temp := ControlService(hService, SERVICE_CONTROL_STOP, serviceStatus);
         if not temp then dwStatus := GetLastError();
      end else dwStatus := GetLastError();
    
      if (hService <> 0) then CloseServiceHandle(hService);
      result := dwStatus;
    end;
    
    //-------------------------------------------
    function TSysDriver.Remove:  DWORD;
    //-------------------------------------------
    Var
      hService: SC_HANDLE;
      dwStatus: DWORD;
      temp: LongBool;
    Begin
      dwStatus := Stop;  // ignore result
    
      // get a handle to the service
      hService := OpenService(hSCMan, PChar(DriverName), SERVICE_ALL_ACCESS);
      if hService <> 0 then
      Begin
         temp := DeleteService(hService);
         if not temp then dwStatus := GetLastError();
      end else dwStatus := GetLastError();
    
      if (hService <> 0) then CloseServiceHandle(hService);
      result := dwStatus;
    end;
    
    //=============================================================
    // Device Open/Close functions
    //=============================================================
    
    //-------------------------------------------
    function TSysDriver.DeviceOpen:  DWORD;
    //-------------------------------------------
    Var
      dwStatus: DWORD;
    Begin
      dwStatus := 0;
    
      if hDevice <> INVALID_HANDLE_VALUE then DeviceClose;
    
      // get a handle to the device
      hDevice := CreateFile(
                 { lpFileName: PChar            } PChar('\.'+ DEVICE_NAME_STRING),
                 { dwDesiredAccess: integer     } GENERIC_READ or GENERIC_WRITE,
                 { dwShareMode: Integer         } 0,
                 { lpSecurityAttributes         } nil,
                 { dwCreationDisposition: DWORD } OPEN_EXISTING,
                 { dwFlagsAndAttributes: DWORD  } FILE_ATTRIBUTE_NORMAL,
                 { hTemplateFile: THandle       } 0);
    
      if hDevice = INVALID_HANDLE_VALUE then
      Begin
        dwStatus := GetLastError();
      end else
      begin
        HaveLoad:=True;
      end; 
    
      result := dwStatus;
    end;
    
    //-------------------------------------------
    function TSysDriver.DeviceClose:  DWORD;
    //-------------------------------------------
    Var
      dwStatus: DWORD;
    Begin
      dwStatus := 0;
      if (hDevice <> INVALID_HANDLE_VALUE) then CloseHandle(hDevice);
      hDevice := INVALID_HANDLE_VALUE;
      result := dwStatus; { assume that it went OK? }
    end;
    
    //-------------------------------------------
    function TSysDriver.IOControl(Cmd: DWORD; inBuf: Pointer; inSize: DWORD;
          outbuf: Pointer; var outSize: DWORD): Boolean;
    //-------------------------------------------
    Var
      BytesReturned: DWORD;
      MyControlCode: DWORD;
    
    Begin
      Result := False;
    
      if hDevice = INVALID_HANDLE_VALUE then Exit;
    
      MyControlCode := Cmd;//CTL_CODE(BaseControlCode, Cmd , METHOD_BUFFERED, FILE_ANY_ACCESS);
    
      BytesReturned := 0;
      Result := DeviceIoControl(hDevice, MyControlCode ,
              { in buffer  (to driver)   }  InBuf,  inSize,
              { out buffer (from driver) }  OutBuf, outSize,
    
              BytesReturned, nil);
    end;
    
    end.

    http://www.lsworks.net/article/72.html

  • 相关阅读:
    start internal web server in .net 2.0
    windows scripts tips
    move vs2k3 to vs2k5
    w2k telnet port change
    Webservice自动表生成TableForGen
    用C#改写Head First Design PatternsSingleTon(原创)
    使用反射创建动态模块
    使用反射将委托挂钩
    用C#改写Head First Design PatternsState(原创)
    用Xmlhttp无刷新更新DIV
  • 原文地址:https://www.cnblogs.com/findumars/p/4998884.html
Copyright © 2011-2022 走看看