Brett, welcome.
Note that you are trying to debug user-mode code (kernel32!CreateFileW is user-mode code...) from a kernel-mode debug session. To do this you must ensure the context of your process is actually used (its virtual addresses space paged-in etc.). A simple
.process ?? and
.reload /user should fix your memory issues described.
A few more words
The transition from user-mode to kernel-mode is accomplished trough an opcode called
sysenter/sysexecute (Intel/AMD). You can see this if you debug a few steps into kernel32!CreateFileW. The call stack will then look like this:
0:000> k
ChildEBP RetAddr
0012f7a0 7c90d0ba ntdll!KiFastSystemCall+0x2
0012f7a4 7c8109b6 ntdll!NtCreateFile+0xc
0012f83c 0045c771 kernel32!CreateFileW+0x35f
And the disassembly of ntdll!KiFastSystemCall:
0:000> uf ntdll!KiFastSystemCall
ntdll!KiFastSystemCall:
7c90e510 8bd4 mov edx,esp
7c90e512 0f34
sysenter
7c90e514 c3 ret
As soon as sysenter is executed we switch execution to kernel-mode. Unfortunately we cannot debug this transition from WinDbg directly so there is a little bit more to know about system services and their implementation on Windows. If we take a look at ntdll.dll and its implementation we see something like this on Windows XP SP3:
Note how a different value is stored into register EAX for each function? Basically this is an index into the system-service dispatch table (nt!KiServiceTable) which is located in the kernel; this table holds function pointers to all available system services. The system service dispatcher conveniently uses this index from EAX to get a function pointer and calls the function thereafter. With this knowledge we can set the following breakpoint in kd for our CreateFile:
0: kd> bp nt!KiFastCallEntry ".if (@eax == 0x25) { .echo ***** CreateFile called *****;} .else {g;};"
This breakpoint will break whenever an application calls CreateFile in user-mode and will do nothing for other services requested.
Anyway you can use the same "trick" for any imaginable system service by simply changing the index-constant in the breakpoint. Note that the index will differ between different Windows versions and service packs. For example, if ntdll!NtCreateFile has index 0x25 on Windows XP SP3 it might have the value 0x34 on Vista. Fortunately we can easily obtain the correct value by examining ntdll.dll...
I hope this helps,
Robert