I hope your daughter doesn't get nightmares from seeing the inside of Windows, many people do 
 
You asked me for some ideas as to where to go from here. If you want to reverse drivers you'll need to understand driver structure. The best way is to create your own driver skeleton, disassemble it so as to recognize standard constructs in assembly, learn WinDbg methods of tracing it, etc.
I think one of the best summaries of driver structure is an old tutorial written by one of our members:
Kernel Mode Driver Tutorial: Part I: The Skeleton KMD by Clandestiny
http://www.reverse-engineering.info/SystemCoding/SkeletonKMD_Tutorial.htm
or
http://www.woodmann.com/forum/attachment.php?attachmentid=747&d=1062490066
Other excellent resources:
Device Driver Development for Beginners - Reloaded
http://www.kernelmode.info/forum/viewtopic.php?f=14&t=374
Making your first driver - complete walkthrough
http://articles.sysprogs.org/visualddk/firstdriver/
System Coding
http://www.reverse-engineering.info/documents/31.html
Kernel Mode Driver Development Kit for MASM32 programmers
http://www.freewebs.com/four-f/
 Here's an example of what you could do. For arguments sake lets say you wanted to trace the IOCTL codes (the usermode/kernelmode communication) for beep.sys. Start up your WinDbg/VM and display the DRIVER_OBJECT details for beep.sys with extended flag information.
Code:
kd> !drvobj beep 7
Driver object (8c6299e0) is for:
 \Driver\Beep
DriverEntry:   8e56e03e    
DriverStartIo: 8e56b248    
DriverUnload:  8e56b2c6    
Dispatch routines:
[00] IRP_MJ_CREATE                      8e56b1ac
..
[02] IRP_MJ_CLOSE                       8e56b1fe
..
[0e] IRP_MJ_DEVICE_CONTROL              8e56b116
For IOCTL codes we are interested in the IRP_MJ_DEVICE_CONTROL Dispatch routine function address. So let's set a breakpoint on that address and trigger a beep and see what happens. 
 
Type Ctrl-G in a command window in the VM and press Enter and it should beep. Don't ask me why, I just found that on the net. You could also use the funky NirCmd utility to create a beep and it should also work.
http://www.nirsoft.net/utils/nircmd.html
Windbg should break and you'll see this:
Code:
...
8e56b11b 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
8e56b11e 8b4160          mov     eax,dword ptr [ecx+60h]
8e56b121 8b500c          mov     edx,dword ptr [eax+0Ch]
8e56b124 81ea00000100    sub     edx,10000h
8e56b12a 56              push    esi
8e56b12b 743c            je      8e56b169
Those first 3 lines are important and you'll see them in various guises in the majority of drivers, but we need to understand them.
Disassemble beep.sys in IDA and find the function, which tells us that the first structure of interest is an _IRP
Code:
:00011116 ; int __stdcall BeepDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
:00011116 _BeepDeviceControl@8 proc near          ; DATA XREF: DriverEntry(x,x)+BE
:00011116
:00011116 DeviceObject    = dword ptr  8
:00011116 Irp             = dword ptr  0Ch
:00011116
...
:0001111B                 mov     ecx, [ebp+Irp]  ; Irp
:0001111E                 mov     eax, [ecx+60h]
:00011121                 mov     edx, [eax+0Ch]
:00011124                 sub     edx, 10000h
:0001112A                 push    esi
:0001112B                 jz      short loc_11169
Look at the definition of _IRP in the WinDDK wdm.h file, or Clandestiny's tutorial and try to figure out what is at the offset [ecx+60h] (PIRP+60h).
You could also use WinDbg. Trace past the line 8e56b11b and type
Code:
kd> dt nt!_IRP @ecx -r
   +0x000 Type             : 0n6
   +0x002 Size             : 0x94
...
   +0x040 Tail             : <unnamed-tag>
      +0x000 Overlay          : <unnamed-tag>
...
         +0x020 CurrentStackLocation : 0x8ba04898 _IO_STACK_LOCATION 
[ecx+60h] is therefore _IO_STACK_LOCATION.
In code this would be equivalent to
Code:
    PIO_STACK_LOCATION      IrpStack;
    // Get pointer to IRP stack location
    IrpStack = IoGetCurrentIrpStackLocation( Irp );
 The next line we must parse is [eax+0Ch], or PIO_STACK_LOCATION + 0Ch.  In this case the definition of the offset 0Ch is a union, the exact meaning being dependant on the service being invoked. In our case it's DeviceIoControl and we can work out from the structure definitions that offset 0Ch is IoControlCode.
Code:
    ULONG ioControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;    
I know that's a lot of theory for 3 little lines, but now we've been able to interpret the code so we know that EDX contains the IOCTL code being passed from usermode through the DeviceIoControl API.  From here we can just trace logically to wherever the code takes us to each of the individual functions.
btw, a handy trick for static disassembly is to add the IRP and IO_STACK_LOCATION structure definitions in IDA and use them to name the structure offsets, it would look like this.  
Code:
:0001111B   mov     ecx, [ebp+Irp]  ; Irp
:0001111E   mov     eax, dword ptr [ecx+IRP.Tail.Overlay.anonymous_1.anonymous_0]
:00011121   mov     edx, [eax+IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode]
Just so you don't think it's always this straightforward, say we do the same thing with Process Explorer:
Code:
kd> !drvobj procexp100 7
Driver object (8b8e6488) is for:
 \Driver\PROCEXP100
Dispatch routines:
[00] IRP_MJ_CREATE                      9bbfcd46
..
[02] IRP_MJ_CLOSE                       9bbfcd46
[..
[0e] IRP_MJ_DEVICE_CONTROL              9bbfcd46
Notice that all 3 IRP_MJ functions have the same address. This is a common way of writing a driver, unlike the beep.sys example.  Breakpoint on that address and you'll see familiar code, plus a switch statement line pointing the way to IRP_MJ_DEVICE_CONTROL:
cmp     dl,0Eh // [0e] IRP_MJ_DEVICE_CONTROL
If you wish, take a look at the driver source code in my latest blog post to see how that is constructed:
Code:
    // Dispatch on MajorFunction
    switch (IrpStack->MajorFunction)
    {
        // Default these two IRPs
        case IRP_MJ_CREATE:
        case IRP_MJ_CLOSE:
        break;    
        
        case IRP_MJ_DEVICE_CONTROL:
            // Handle the GUI IOCTL requests
Well I've beat that to death like a rented mule... Enough for now.
Kayaker