Creating and using servicies for kernel drivers

I create a driver(SYS).
I would like to create a service and work with it (allowing users to use it or not).I dont know what to do so please give me a sample of a SYS and a GUI which interact via control codes and how can administrator set rights for users to use the SYS or not. (describe the steps to do please)
Thanks
buzaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
Go to http://www.sysinternals.com and download the source code of 'regmon' (http://www.sysinternals.com/regmon.htm). This is a driver/GUI combination that does exactly what you need.

/****************************************************************************
*
*    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
*
*    PURPOSE:  Processes messages for the statistics window.
*
****************************************************************************/
LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam)
{
      DWORD                  nb, versionNumber;
      DWORD                  length, type, tag, driverStart;
      TCHAR                  Path[ MAX_PATH ];
      HKEY                  hDriverKey;
      static TCHAR      group[] = "System Bus Extender";
      static TCHAR      driverPath[ MAX_PATH ];
      TCHAR                  systemRoot[ MAX_PATH ];
      static TCHAR      logFile[ MAX_PATH ];
      LPTOOLTIPTEXT      lpToolTipText;
      static TCHAR      szBuf[128];
      LPFINDREPLACE      findMessageInfo;
      DWORD                  majorver, minorver;
      TCHAR                  *File;
      WIN32_FIND_DATA findData;
      HANDLE                  findHandle;
      DWORD                  startTime;
      RECT                  rc;
      POINT                  hitPoint;
      LOGFONT                  lf;
      CHOOSEFONT            chf;
      TEXTMETRIC            textMetrics;
      RECT                  listRect;
      HDC                        hDC;
      PAINTSTRUCT            Paint;
      MENUITEMINFO      bootMenuItem;

      switch ( message ) {

            case WM_CREATE:

                  // get hourglass icon ready
                  hHourGlass = LoadCursor( NULL, IDC_WAIT );

                  // post hourglass icon
                  SetCapture(hWnd);
                  hSaveCursor = SetCursor(hHourGlass);

                  // determine performance counter frequency
                  QueryPerformanceFrequency( &PerfFrequency );

                  // Create the toolbar control - use modern style if available.
                  GetDLLVersion( "comctl32.dll", &majorver, &minorver );
                  if( majorver > 4 || (majorver == 4 && minorver >= 70) ) {
                        hWndToolbar = CreateToolbarEx(
                              hWnd, TOOLBAR_FLAT | WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,  
                              ID_TOOLBAR, NUMTOOLBUTTONS, hInst, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtons,
                              NUMBUTTONS, 16,16,16,15, sizeof(TBBUTTON));
                  } else {
                        hWndToolbar = CreateToolbarEx(
                              hWnd, WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,  
                              ID_TOOLBAR, NUMTOOLBUTTONS, hInst, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtonsOld,
                              NUMBUTTONSOLD, 16,16,16,15, sizeof(TBBUTTON));
                  }
                  if (hWndToolbar == NULL )
                        MessageBox (NULL, _T("Toolbar not created!"), NULL, MB_OK );

                  // Create the ListBox within the main window
                  hWndList = CreateList( hWnd );
                  if ( hWndList == NULL )
                        MessageBox( NULL, _T("List not created!"), NULL, MB_OK );

                // open the handle to the device
                  if( IsNT ) {

                        // Add the log boot menu item
                        bootMenuItem.cbSize = sizeof( bootMenuItem );
                        bootMenuItem.fMask = MIIM_TYPE;
                        bootMenuItem.fType = MFT_SEPARATOR;
                        InsertMenuItem( GetSubMenu( GetMenu(hWnd), 1 ),
                                                GetMenuItemCount( GetSubMenu( GetMenu(hWnd), 1 )),
                                                TRUE, &bootMenuItem );
                        bootMenuItem.fMask = MIIM_TYPE|MIIM_ID;
                        bootMenuItem.fType = MFT_STRING;
                        bootMenuItem.wID = IDM_BOOTLOG;
                        bootMenuItem.dwTypeData = (PCHAR) "Log &Boot";
                        InsertMenuItem( GetSubMenu( GetMenu(hWnd), 1 ),
                                                GetMenuItemCount( GetSubMenu( GetMenu(hWnd), 1 )),
                                                TRUE, &bootMenuItem );

                        GetCurrentDirectory( sizeof Path, Path );
                        sprintf( Path+lstrlen(Path), _T("\\%s"), SYS_FILE );

                        findHandle = FindFirstFile( Path, &findData );
                        if( findHandle == INVALID_HANDLE_VALUE ) {

                              if( !SearchPath( NULL, SYS_FILE, NULL, sizeof(Path), Path, &File ) ) {

                                    sprintf( msgbuf, _T("%s was not found."), SYS_FILE );
                                    return Abort( hWnd, msgbuf );
                              }

                        } else FindClose( findHandle );

                        // read driver start type to see if boot-logging is enabled
                        driverStart = SERVICE_DEMAND_START;
                        if( RegOpenKey( HKEY_LOCAL_MACHINE, REGMON_DRIVER_KEY, &hDriverKey ) ==
                              ERROR_SUCCESS ) {

                              length = sizeof( driverStart );
                              RegQueryValueEx( hDriverKey, "Start", NULL, &type,
                                    (PBYTE) &driverStart, &length);
                              RegCloseKey( hDriverKey );
                        }
                        BootLog = (driverStart != SERVICE_DEMAND_START);

                        // check boot logging menu item if boot start
                        CheckMenuItem( GetMenu(hWnd), IDM_BOOTLOG,
                                    MF_BYCOMMAND|(BootLog?MF_CHECKED:MF_UNCHECKED) );

                        // copy the driver to <winnt>\system32\drivers so that we can do
                        // boot-time monitoring with the flip of a bit
                        // get the system root
                        if( !GetEnvironmentVariable( "SYSTEMROOT", systemRoot, sizeof(systemRoot))) {

                              strcpy( msgbuf, _T("Could not resolve SYSTEMROOT environment variable") );
                              return Abort( hWnd, msgbuf );
                        }
                        sprintf( logFile, _T("%s\\REGMON.LOG"), systemRoot );
                        sprintf( driverPath, _T("%s\\system32\\drivers\\%s"),
                                                systemRoot, SYS_FILE );
                        if( !CopyFile( Path, driverPath, FALSE )) {

                              sprintf( msgbuf, _T("Unable to copy %s to %s\n\n")
                                    _T("Make sure that regsys.sys is in the current directory."),
                                    SYS_NAME, driverPath );
                              return Abort( hWnd, msgbuf );
                        }

                        if ( ! LoadDeviceDriver( SYS_NAME, driverPath, &SysHandle ) )  {

                              sprintf( msgbuf, _T("Opening %s (%s): error %d"), SYS_NAME, Path,
                                                      GetLastError( ) );
                              return Abort( hWnd, msgbuf );
                        }

                        // Correct driver version?
                        if ( ! DeviceIoControl(      SysHandle, IOCTL_REGMON_VERSION,
                                                            NULL, 0, &versionNumber, sizeof(DWORD), &nb, NULL ) ||
                                    versionNumber != REGMON_VERSION )
                        {
                              MessageBox( hWnd, _T("Regmon located a driver with the wrong version.\n")
                                    _T("\nIf you just installed a new version you must reboot before you are")
                                    _T("able to use it."), APPNAME, MB_ICONERROR);
                              return -1;
                        }

                  } else {

                        // Win9x
                  }

                  // Set the filter
                  FilterDefinition.excludefilter[0] = 0;
                  FilterDefinition.includefilter[0] = 0;
                  if( strcmp( ExcludeString, " " ) )
                        strcpy( FilterDefinition.excludefilter, ExcludeString );
                  if( strcmp( FilterString, " " ) )
                        strcpy( FilterDefinition.includefilter, FilterString );

                  // See if they want to keep any filters
                  if( strcmp( FilterString, "*" ) ||
                        (*ExcludeString && strcmp( ExcludeString, " "))) {

                        DialogBox( hInst, TEXT("InitFilter"), hWnd, (DLGPROC) FilterProc );
                  } else {

                        if ( ! DeviceIoControl(      SysHandle, IOCTL_REGMON_SETFILTER,
                                                            (PVOID) &FilterDefinition, sizeof(FilterDefinition),
                                                            NULL, 0, &nb, NULL ) )      {

                              return Abort( hWnd, _T("Couldn't access device driver") );
                        }
                  }

                  // Have driver zero information
                  if ( ! DeviceIoControl(      SysHandle, IOCTL_REGMON_ZEROSTATS,
                                                      NULL, 0, NULL, 0, &nb, NULL ) ) {

                        return Abort( hWnd, _T("Couldn't access device driver") );
                  }

                  // Start up timer to periodically update screen
                  SetTimer( hWnd,      1, 500/*ms*/, NULL );

                  // Have driver turn on hooks
                  if ( ! DeviceIoControl(      SysHandle, IOCTL_REGMON_HOOK,
                                                      NULL, 0, NULL, 0, &nb, NULL ) )      {

                        return Abort( hWnd, _T("Couldn't access device driver") );
                  }
                  
                  // Initialization done
                  SetCursor( hSaveCursor );
                  ReleaseCapture();
                  return FALSE;

            case WM_NOTIFY:


            case WM_COMMAND:

                  switch ( LOWORD( wParam ) )       {

                        // stats related commands to send to driver
                        case IDM_CLEAR:
                              // Have driver zero information
                              if ( ! DeviceIoControl(      SysHandle, IOCTL_REGMON_ZEROSTATS,
                                                                  NULL, 0, NULL, 0, &nb, NULL ) )
                              {
                                    Abort( hWnd, _T("Couldn't access device driver") );
                                    return TRUE;
                              }
                              // Update statistics windows
                              UpdateStatistics( hWnd, hWndList, NULL, 0, TRUE );
                              return FALSE;

                        case IDM_HELP:
                              WinHelp(hWnd, _T("regmon.hlp"), HELP_CONTENTS, 0L);
                              return 0;

                        case IDM_HISTORY:
                              DialogBox( hInst, TEXT("History"), hWnd, (DLGPROC) HistoryProc );
                              return 0;

                        case IDM_TIME:
                              // Toggle time format
                              ClockTime = !ClockTime;
                              CheckMenuItem( GetMenu(hWnd), IDM_TIME,
                                                      MF_BYCOMMAND|(ClockTime?MF_CHECKED:MF_UNCHECKED) );
                              SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_TIME, (ClockTime?10:11) );
                              InvalidateRect( hWndToolbar, NULL, TRUE );
                              return FALSE;
                        
                        case IDM_FIND:
                              // search the listview
                              if( !hWndFind ) {
                                    PrevMatch = FALSE;
                                    PopFindDialog( hWnd );
                              } else {

                                    SetFocus( hWndFind );
                              }
                              return 0;

                        case IDM_FINDAGAIN:
                              if( PrevMatch ) {
                                    SetCapture( hWndFind );
                                    hSaveCursor = SetCursor(hHourGlass);
                                    if (FindInListview( hWnd, &FindTextInfo ) ) {
                                          Autoscroll = FALSE;
                                          CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
                                                                  MF_BYCOMMAND|MF_UNCHECKED );
                                          SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_AUTOSCROLL, 3 );
                                    }
                                    SetCursor( hSaveCursor );
                                    ReleaseCapture();
                              }
                              return 0;

                        case IDM_CAPTURE:
                              // Read statistics from driver
                              Capture = !Capture;
                              CheckMenuItem( GetMenu(hWnd), IDM_CAPTURE,
                                                      MF_BYCOMMAND|(Capture?MF_CHECKED:MF_UNCHECKED) );

                              // Have driver turn on hooks
                              if ( ! DeviceIoControl(      SysHandle, Capture ? IOCTL_REGMON_HOOK :
                                                                  IOCTL_REGMON_UNHOOK,
                                                                  NULL, 0, NULL, 0, &nb, NULL ) )
                              {
                                    Abort( hWnd, _T("Couldn't access device driver") );
                                    return TRUE;
                              }
                              SendMessage( hWndToolbar, TB_CHANGEBITMAP, IDM_CAPTURE, (Capture?2:1) );
                              InvalidateRect( hWndToolbar, NULL, TRUE );
                              return FALSE;

//....

}


//======================================================================
//         D E V I C E - D R I V E R  R O U T I N E S
//======================================================================

//----------------------------------------------------------------------
//
// RegmonDeviceControl
//
//----------------------------------------------------------------------
BOOLEAN  RegmonDeviceControl( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
                              IN PVOID InputBuffer, IN ULONG InputBufferLength,
                              OUT PVOID OutputBuffer, IN ULONG OutputBufferLength,
                              IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus,
                              IN PDEVICE_OBJECT DeviceObject ) {
    BOOLEAN                 retval = FALSE;
    PSTORE_BUF              old;

    //
    // Its a message from our GUI!
    //
    IoStatus->Status      = STATUS_SUCCESS; // Assume success
    IoStatus->Information = 0;              // Assume nothing returned
    switch ( IoControlCode ) {

    case IOCTL_REGMON_VERSION:

        //
        // Version #
        //
        if ( OutputBufferLength < sizeof(ULONG) ||
             OutputBuffer == NULL ) {

            IoStatus->Status = STATUS_INVALID_PARAMETER;
            break;
        }
           
        *(ULONG *)OutputBuffer = REGMON_VERSION;
        IoStatus->Information = sizeof(ULONG);
        break;

    case IOCTL_REGMON_HOOK:
        DbgPrint (("Regmon: hook\n"));
        HookRegistry();
        break;

    case IOCTL_REGMON_UNHOOK:
        DbgPrint(("Regmon: unhook\n"));
        UnhookRegistry();
        break;

    case IOCTL_REGMON_ZEROSTATS:

        //
        // Zero contents of buffer
        //
        DbgPrint (("Regmon: zero stats\n"));
        MUTEX_WAIT( StoreMutex );
        while ( Store->Next )  {
            // release next
            old = Store->Next;
            Store->Next = old->Next;
            MUTEX_WAIT( StoreMutex );
            ExFreePool( old );
            NumStore--;
            MUTEX_RELEASE( StoreMutex );
        }
        Store->Len = 0;

        //
        // Reset sequence and relative start time
        //
        Sequence = 0;
        StartTime = KeQueryPerformanceCounter( NULL );
        MUTEX_RELEASE( StoreMutex );
        break;

    case IOCTL_REGMON_GETSTATS:

        //
        // Copy buffer into user space.
        //
        DbgPrint (("Regmon: get stats\n"));

        //
        // Probe the output buffer
        //
        try {                

            ProbeForWrite( OutputBuffer,
                           OutputBufferLength,
                           sizeof( UCHAR ));

        } except( EXCEPTION_EXECUTE_HANDLER ) {

            IoStatus->Status = STATUS_INVALID_PARAMETER;
            return FALSE;
        }            

        MUTEX_WAIT( StoreMutex );
        if ( MAX_STORE > OutputBufferLength )  {

            //
            // Output buffer isn't big enough
            //
            MUTEX_RELEASE( StoreMutex );
            IoStatus->Status = STATUS_INVALID_PARAMETER;
            return FALSE;

        } else if ( Store->Len  ||  Store->Next ) {

            //
            // Switch to a new store
            //
            RegmonNewStore();

            // Fetch the oldest to give to user
            old = RegmonOldestStore();
            MUTEX_RELEASE( StoreMutex );

            //
            // Copy it
            //
            memcpy( OutputBuffer, old->Data, old->Len );

            //
            // Return length of copied info
            //
            IoStatus->Information = old->Len;

            //
            // Deallocate buffer
            //
            ExFreePool( old );

        } else {
            //
            // No unread data
            //
            MUTEX_RELEASE( StoreMutex );
            IoStatus->Information = 0;
        }
        break;

    case IOCTL_REGMON_SETFILTER:

        //        
        // GUI is updating the filter
        //
        DbgPrint(("Regmon: set filter\n"));

        if ( InputBufferLength < sizeof(FILTER) ||
             InputBuffer == NULL ) {

            IoStatus->Status = STATUS_INVALID_PARAMETER;
            break;
        }

        FilterDef = *(PFILTER) InputBuffer;
        RegmonUpdateFilters();
        break;
 
    default:
        DbgPrint (("Regmon: unknown IRP_MJ_DEVICE_CONTROL\n"));
        IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }
    return TRUE;
}

Feel free to ask if you need more information!
0
jkrCommented:
To control the access to your driver, you'll have to provide an appropriate security descriptor and call 'NtSetSecutityObject()' for your driver, e.g.

PSID CreateUserSID ( void)
{
    PSID                        psid;

    SID_IDENTIFIER_AUTHORITY    SystemSidAuthority  =   SECURITY_NT_AUTHORITY;

    if  (   !AllocateAndInitializeSid   (   &SystemSidAuthority,
                                            1,
                                            DOMAIN_GROUP_RID_USERS,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            &psid
                                        )
        )
        return ( NULL);

    return ( psid);
}

0
buzaAuthor Commented:
I had that source and I try to do a basic driver which load ,creates himself as a service and then I call a IOCTL....
My problem is that I think I don't understand some basic mechanismes of loading a driver and dispatching ioctl codes.
I create a driver I load it with CreateService,CreateFile,StartService bla,bla,bla.....But it gives me an error message  when I send IOCTL codes(NTSTATUS_ACCES_VIOLATION).I do what in a FastIoDispatchRoutine.
What I dont understand is where shoud I dispatch IOCTL codes: in IRP_MJ_DEVICE_CONTROL (I guess )in my dispatch routine  or in a FastIoDispatchRoutine (see filemon)? .I dont know what to do and what are Fast IO routine.Could you tell me?
Thanks for comment! :)
0
PIGCommented:
Try that. http://www.research.microsoft.com/os/galenh/proxy/
It is a project for file system driver with service communication with driver. All is OLE interface based. Have some examples for use and all is write very clean. If You want can be download source. I use these source in my driver in moment. To my regret I am not still ready. But all samples are very good.


And here http://www.osr.com/insider/1997/krndll.htm have some documentaion for kernel mode dll's that will be too  interesting for You.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.