riched20: Send WM_CHAR notifications.
[wine] / dlls / ntoskrnl.exe / ntoskrnl.c
1 /*
2  * ntoskrnl.exe implementation
3  *
4  * Copyright (C) 2007 Alexandre Julliard
5  * Copyright (C) 2010 Damjan Jovanovic
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdarg.h>
26
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29
30 #include "ntstatus.h"
31 #define WIN32_NO_STATUS
32 #include "windef.h"
33 #include "winternl.h"
34 #include "excpt.h"
35 #include "winioctl.h"
36 #include "ddk/ntddk.h"
37 #include "wine/unicode.h"
38 #include "wine/server.h"
39 #include "wine/list.h"
40 #include "wine/debug.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
43 WINE_DECLARE_DEBUG_CHANNEL(relay);
44
45 BOOLEAN KdDebuggerEnabled = FALSE;
46
47 extern LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs );
48
49 KSYSTEM_TIME KeTickCount = { 0, 0, 0 };
50
51 typedef struct _KSERVICE_TABLE_DESCRIPTOR
52 {
53     PULONG_PTR Base;
54     PULONG Count;
55     ULONG Limit;
56     PUCHAR Number;
57 } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
58
59 KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4] = { { 0 } };
60
61 typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
62 typedef void (WINAPI *PCREATE_THREAD_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
63
64 static struct list Irps = LIST_INIT(Irps);
65
66 struct IrpInstance
67 {
68     struct list entry;
69     IRP *irp;
70 };
71
72 /* tid of the thread running client request */
73 static DWORD request_thread;
74
75 /* pid/tid of the client thread */
76 static DWORD client_tid;
77 static DWORD client_pid;
78
79 #ifdef __i386__
80 #define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
81     __ASM_STDCALL_FUNC( name, 4, \
82                        "popl %eax\n\t" \
83                        "pushl %ecx\n\t" \
84                        "pushl %eax\n\t" \
85                        "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(4))
86 #define DEFINE_FASTCALL2_ENTRYPOINT( name ) \
87     __ASM_STDCALL_FUNC( name, 8, \
88                        "popl %eax\n\t" \
89                        "pushl %edx\n\t" \
90                        "pushl %ecx\n\t" \
91                        "pushl %eax\n\t" \
92                        "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(8))
93 #define DEFINE_FASTCALL3_ENTRYPOINT( name ) \
94     __ASM_STDCALL_FUNC( name, 12, \
95                        "popl %eax\n\t" \
96                        "pushl %edx\n\t" \
97                        "pushl %ecx\n\t" \
98                        "pushl %eax\n\t" \
99                        "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(12))
100 #endif
101
102 static inline LPCSTR debugstr_us( const UNICODE_STRING *us )
103 {
104     if (!us) return "<null>";
105     return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) );
106 }
107
108 static HANDLE get_device_manager(void)
109 {
110     static HANDLE device_manager;
111     HANDLE handle = 0, ret = device_manager;
112
113     if (!ret)
114     {
115         SERVER_START_REQ( create_device_manager )
116         {
117             req->access     = SYNCHRONIZE;
118             req->attributes = 0;
119             if (!wine_server_call( req )) handle = wine_server_ptr_handle( reply->handle );
120         }
121         SERVER_END_REQ;
122
123         if (!handle)
124         {
125             ERR( "failed to create the device manager\n" );
126             return 0;
127         }
128         if (!(ret = InterlockedCompareExchangePointer( &device_manager, handle, 0 )))
129             ret = handle;
130         else
131             NtClose( handle );  /* somebody beat us to it */
132     }
133     return ret;
134 }
135
136 /* process an ioctl request for a given device */
137 static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
138                                void *out_buff, ULONG *out_size )
139 {
140     IRP irp;
141     MDL mdl;
142     IO_STACK_LOCATION irpsp;
143     PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
144     NTSTATUS status;
145     LARGE_INTEGER count;
146
147     TRACE( "ioctl %x device %p in_size %u out_size %u\n", code, device, in_size, *out_size );
148
149     /* so we can spot things that we should initialize */
150     memset( &irp, 0x55, sizeof(irp) );
151     memset( &irpsp, 0x66, sizeof(irpsp) );
152     memset( &mdl, 0x77, sizeof(mdl) );
153
154     irp.RequestorMode = UserMode;
155     if ((code & 3) == METHOD_BUFFERED)
156     {
157         irp.AssociatedIrp.SystemBuffer = HeapAlloc( GetProcessHeap(), 0, max( in_size, *out_size ) );
158         if (!irp.AssociatedIrp.SystemBuffer)
159             return STATUS_NO_MEMORY;
160         memcpy( irp.AssociatedIrp.SystemBuffer, in_buff, in_size );
161     }
162     else
163         irp.AssociatedIrp.SystemBuffer = in_buff;
164     irp.UserBuffer = out_buff;
165     irp.MdlAddress = &mdl;
166     irp.Tail.Overlay.s.u2.CurrentStackLocation = &irpsp;
167     irp.UserIosb = NULL;
168
169     irpsp.MajorFunction = IRP_MJ_DEVICE_CONTROL;
170     irpsp.Parameters.DeviceIoControl.OutputBufferLength = *out_size;
171     irpsp.Parameters.DeviceIoControl.InputBufferLength = in_size;
172     irpsp.Parameters.DeviceIoControl.IoControlCode = code;
173     irpsp.Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
174     irpsp.DeviceObject = device;
175     irpsp.CompletionRoutine = NULL;
176
177     mdl.Next = NULL;
178     mdl.Size = 0;
179     mdl.StartVa = out_buff;
180     mdl.ByteCount = *out_size;
181     mdl.ByteOffset = 0;
182
183     device->CurrentIrp = &irp;
184
185     KeQueryTickCount( &count );  /* update the global KeTickCount */
186
187     if (TRACE_ON(relay))
188         DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
189                  GetCurrentThreadId(), dispatch, device, &irp );
190
191     status = dispatch( device, &irp );
192
193     if (TRACE_ON(relay))
194         DPRINTF( "%04x:Ret  driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
195                  GetCurrentThreadId(), dispatch, device, &irp, status );
196
197     *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
198     if ((code & 3) == METHOD_BUFFERED)
199     {
200         if (out_buff) memcpy( out_buff, irp.AssociatedIrp.SystemBuffer, *out_size );
201         HeapFree( GetProcessHeap(), 0, irp.AssociatedIrp.SystemBuffer );
202     }
203     return irp.IoStatus.u.Status;
204 }
205
206
207 /***********************************************************************
208  *           wine_ntoskrnl_main_loop   (Not a Windows API)
209  */
210 NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
211 {
212     HANDLE manager = get_device_manager();
213     obj_handle_t ioctl = 0;
214     NTSTATUS status = STATUS_SUCCESS;
215     ULONG code = 0;
216     void *in_buff, *out_buff = NULL;
217     DEVICE_OBJECT *device = NULL;
218     ULONG in_size = 4096, out_size = 0;
219     HANDLE handles[2];
220
221     request_thread = GetCurrentThreadId();
222
223     if (!(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size )))
224     {
225         ERR( "failed to allocate buffer\n" );
226         return STATUS_NO_MEMORY;
227     }
228
229     handles[0] = stop_event;
230     handles[1] = manager;
231
232     for (;;)
233     {
234         SERVER_START_REQ( get_next_device_request )
235         {
236             req->manager = wine_server_obj_handle( manager );
237             req->prev = ioctl;
238             req->status = status;
239             wine_server_add_data( req, out_buff, out_size );
240             wine_server_set_reply( req, in_buff, in_size );
241             if (!(status = wine_server_call( req )))
242             {
243                 code       = reply->code;
244                 ioctl      = reply->next;
245                 device     = wine_server_get_ptr( reply->user_ptr );
246                 client_tid = reply->client_tid;
247                 client_pid = reply->client_pid;
248                 in_size    = reply->in_size;
249                 out_size   = reply->out_size;
250             }
251             else
252             {
253                 ioctl = 0; /* no previous ioctl */
254                 out_size = 0;
255                 in_size = reply->in_size;
256             }
257         }
258         SERVER_END_REQ;
259
260         switch(status)
261         {
262         case STATUS_SUCCESS:
263             HeapFree( GetProcessHeap(), 0, out_buff );
264             if (out_size) out_buff = HeapAlloc( GetProcessHeap(), 0, out_size );
265             else out_buff = NULL;
266             status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
267             break;
268         case STATUS_BUFFER_OVERFLOW:
269             HeapFree( GetProcessHeap(), 0, in_buff );
270             in_buff = HeapAlloc( GetProcessHeap(), 0, in_size );
271             /* restart with larger buffer */
272             break;
273         case STATUS_PENDING:
274             if (WaitForMultipleObjects( 2, handles, FALSE, INFINITE ) == WAIT_OBJECT_0)
275             {
276                 HeapFree( GetProcessHeap(), 0, in_buff );
277                 HeapFree( GetProcessHeap(), 0, out_buff );
278                 return STATUS_SUCCESS;
279             }
280             break;
281         }
282     }
283 }
284
285
286 /***********************************************************************
287  *           IoAcquireCancelSpinLock  (NTOSKRNL.EXE.@)
288  */
289 void WINAPI IoAcquireCancelSpinLock(PKIRQL irql)
290 {
291     FIXME("(%p): stub\n", irql);
292 }
293
294
295 /***********************************************************************
296  *           IoReleaseCancelSpinLock  (NTOSKRNL.EXE.@)
297  */
298 void WINAPI IoReleaseCancelSpinLock(PKIRQL irql)
299 {
300     FIXME("(%p): stub\n", irql);
301 }
302
303
304 /***********************************************************************
305  *           IoAllocateDriverObjectExtension  (NTOSKRNL.EXE.@)
306  */
307 NTSTATUS WINAPI IoAllocateDriverObjectExtension( PDRIVER_OBJECT DriverObject,
308                                                  PVOID ClientIdentificationAddress,
309                                                  ULONG DriverObjectExtensionSize,
310                                                  PVOID *DriverObjectExtension )
311 {
312     FIXME( "stub: %p, %p, %u, %p\n", DriverObject, ClientIdentificationAddress,
313             DriverObjectExtensionSize, DriverObjectExtension );
314     return STATUS_NOT_IMPLEMENTED;
315 }
316
317
318 /***********************************************************************
319  *           IoGetDriverObjectExtension  (NTOSKRNL.EXE.@)
320  */
321 PVOID WINAPI IoGetDriverObjectExtension( PDRIVER_OBJECT DriverObject,
322                                          PVOID ClientIdentificationAddress )
323 {
324     FIXME( "stub: %p, %p\n", DriverObject, ClientIdentificationAddress );
325     return NULL;
326 }
327
328
329 /***********************************************************************
330  *           IoInitializeIrp  (NTOSKRNL.EXE.@)
331  */
332 void WINAPI IoInitializeIrp( IRP *irp, USHORT size, CCHAR stack_size )
333 {
334     TRACE( "%p, %u, %d\n", irp, size, stack_size );
335
336     RtlZeroMemory( irp, size );
337
338     irp->Type = IO_TYPE_IRP;
339     irp->Size = size;
340     InitializeListHead( &irp->ThreadListEntry );
341     irp->StackCount = stack_size;
342     irp->CurrentLocation = stack_size + 1;
343     irp->Tail.Overlay.s.u2.CurrentStackLocation =
344             (PIO_STACK_LOCATION)(irp + 1) + stack_size;
345 }
346
347
348 /***********************************************************************
349  *           IoInitializeTimer   (NTOSKRNL.EXE.@)
350  */
351 NTSTATUS WINAPI IoInitializeTimer(PDEVICE_OBJECT DeviceObject,
352                                   PIO_TIMER_ROUTINE TimerRoutine,
353                                   PVOID Context)
354 {
355     FIXME( "stub: %p, %p, %p\n", DeviceObject, TimerRoutine, Context );
356     return STATUS_NOT_IMPLEMENTED;
357 }
358
359
360 /***********************************************************************
361  *           IoStartTimer   (NTOSKRNL.EXE.@)
362  */
363 void WINAPI IoStartTimer(PDEVICE_OBJECT DeviceObject)
364 {
365     FIXME( "stub: %p\n", DeviceObject );
366 }
367
368
369 /***********************************************************************
370  *           IoAllocateIrp  (NTOSKRNL.EXE.@)
371  */
372 PIRP WINAPI IoAllocateIrp( CCHAR stack_size, BOOLEAN charge_quota )
373 {
374     SIZE_T size;
375     PIRP irp;
376
377     TRACE( "%d, %d\n", stack_size, charge_quota );
378
379     size = sizeof(IRP) + stack_size * sizeof(IO_STACK_LOCATION);
380     irp = ExAllocatePool( NonPagedPool, size );
381     if (irp == NULL)
382         return NULL;
383     IoInitializeIrp( irp, size, stack_size );
384     irp->AllocationFlags = IRP_ALLOCATED_FIXED_SIZE;
385     if (charge_quota)
386         irp->AllocationFlags |= IRP_LOOKASIDE_ALLOCATION;
387     return irp;
388 }
389
390
391 /***********************************************************************
392  *           IoFreeIrp  (NTOSKRNL.EXE.@)
393  */
394 void WINAPI IoFreeIrp( IRP *irp )
395 {
396     TRACE( "%p\n", irp );
397
398     ExFreePool( irp );
399 }
400
401
402 /***********************************************************************
403  *           IoAllocateErrorLogEntry  (NTOSKRNL.EXE.@)
404  */
405 PVOID WINAPI IoAllocateErrorLogEntry( PVOID IoObject, UCHAR EntrySize )
406 {
407     FIXME( "stub: %p, %u\n", IoObject, EntrySize );
408     return NULL;
409 }
410
411
412 /***********************************************************************
413  *           IoAllocateMdl  (NTOSKRNL.EXE.@)
414  */
415 PMDL WINAPI IoAllocateMdl( PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN ChargeQuota, PIRP Irp )
416 {
417     PMDL mdl;
418     ULONG_PTR address = (ULONG_PTR)VirtualAddress;
419     ULONG_PTR page_address;
420     SIZE_T nb_pages, mdl_size;
421
422     TRACE("(%p, %u, %i, %i, %p)\n", VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);
423
424     if (Irp)
425         FIXME("Attaching the MDL to an IRP is not yet supported\n");
426
427     if (ChargeQuota)
428         FIXME("Charge quota is not yet supported\n");
429
430     /* FIXME: We suppose that page size is 4096 */
431     page_address = address & ~(4096 - 1);
432     nb_pages = (((address + Length - 1) & ~(4096 - 1)) - page_address) / 4096 + 1;
433
434     mdl_size = sizeof(MDL) + nb_pages * sizeof(PVOID);
435
436     mdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mdl_size);
437     if (!mdl)
438         return NULL;
439
440     mdl->Size = mdl_size;
441     mdl->Process = IoGetCurrentProcess();
442     mdl->StartVa = (PVOID)page_address;
443     mdl->ByteCount = Length;
444     mdl->ByteOffset = address - page_address;
445
446     return mdl;
447 }
448
449
450 /***********************************************************************
451  *           IoFreeMdl  (NTOSKRNL.EXE.@)
452  */
453 VOID WINAPI IoFreeMdl(PMDL mdl)
454 {
455     FIXME("partial stub: %p\n", mdl);
456
457     HeapFree(GetProcessHeap(), 0, mdl);
458 }
459
460
461 /***********************************************************************
462  *           IoAllocateWorkItem  (NTOSKRNL.EXE.@)
463  */
464 PIO_WORKITEM WINAPI IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject )
465 {
466     FIXME( "stub: %p\n", DeviceObject );
467     return NULL;
468 }
469
470
471 /***********************************************************************
472  *           IoAttachDeviceToDeviceStack  (NTOSKRNL.EXE.@)
473  */
474 PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
475                                                    DEVICE_OBJECT *target )
476 {
477     TRACE( "%p, %p\n", source, target );
478     target->AttachedDevice = source;
479     source->StackSize = target->StackSize + 1;
480     return target;
481 }
482
483
484 /***********************************************************************
485  *           IoBuildDeviceIoControlRequest  (NTOSKRNL.EXE.@)
486  */
487 PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
488                                            PDEVICE_OBJECT DeviceObject,
489                                            PVOID InputBuffer,
490                                            ULONG InputBufferLength,
491                                            PVOID OutputBuffer,
492                                            ULONG OutputBufferLength,
493                                            BOOLEAN InternalDeviceIoControl,
494                                            PKEVENT Event,
495                                            PIO_STATUS_BLOCK IoStatusBlock )
496 {
497     PIRP irp;
498     PIO_STACK_LOCATION irpsp;
499     struct IrpInstance *instance;
500
501     TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
502            IoControlCode, DeviceObject, InputBuffer, InputBufferLength,
503            OutputBuffer, OutputBufferLength, InternalDeviceIoControl,
504            Event, IoStatusBlock );
505
506     if (DeviceObject == NULL)
507         return NULL;
508
509     irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
510     if (irp == NULL)
511         return NULL;
512
513     instance = HeapAlloc( GetProcessHeap(), 0, sizeof(struct IrpInstance) );
514     if (instance == NULL)
515     {
516         IoFreeIrp( irp );
517         return NULL;
518     }
519     instance->irp = irp;
520     list_add_tail( &Irps, &instance->entry );
521
522     irpsp = IoGetNextIrpStackLocation( irp );
523     irpsp->MajorFunction = InternalDeviceIoControl ?
524             IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
525     irpsp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
526     irp->UserIosb = IoStatusBlock;
527     irp->UserEvent = Event;
528
529     return irp;
530 }
531
532
533 /***********************************************************************
534  *           IoCreateDriver   (NTOSKRNL.EXE.@)
535  */
536 NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
537 {
538     DRIVER_OBJECT *driver;
539     DRIVER_EXTENSION *extension;
540     NTSTATUS status;
541
542     TRACE("(%s, %p)\n", debugstr_us(name), init);
543
544     if (!(driver = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
545                                     sizeof(*driver) + sizeof(*extension) )))
546         return STATUS_NO_MEMORY;
547
548     if ((status = RtlDuplicateUnicodeString( 1, name, &driver->DriverName )))
549     {
550         RtlFreeHeap( GetProcessHeap(), 0, driver );
551         return status;
552     }
553
554     extension = (DRIVER_EXTENSION *)(driver + 1);
555     driver->Size            = sizeof(*driver);
556     driver->DriverInit      = init;
557     driver->DriverExtension = extension;
558     extension->DriverObject   = driver;
559     extension->ServiceKeyName = driver->DriverName;
560
561     status = driver->DriverInit( driver, name );
562
563     if (status)
564     {
565         RtlFreeUnicodeString( &driver->DriverName );
566         RtlFreeHeap( GetProcessHeap(), 0, driver );
567     }
568     return status;
569 }
570
571
572 /***********************************************************************
573  *           IoDeleteDriver   (NTOSKRNL.EXE.@)
574  */
575 void WINAPI IoDeleteDriver( DRIVER_OBJECT *driver )
576 {
577     TRACE("(%p)\n", driver);
578
579     RtlFreeUnicodeString( &driver->DriverName );
580     RtlFreeHeap( GetProcessHeap(), 0, driver );
581 }
582
583
584 /***********************************************************************
585  *           IoCreateDevice   (NTOSKRNL.EXE.@)
586  */
587 NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size,
588                                 UNICODE_STRING *name, DEVICE_TYPE type,
589                                 ULONG characteristics, BOOLEAN exclusive,
590                                 DEVICE_OBJECT **ret_device )
591 {
592     NTSTATUS status;
593     DEVICE_OBJECT *device;
594     HANDLE handle = 0;
595     HANDLE manager = get_device_manager();
596
597     TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n",
598            driver, ext_size, debugstr_us(name), type, characteristics, exclusive, ret_device );
599
600     if (!(device = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*device) + ext_size )))
601         return STATUS_NO_MEMORY;
602
603     SERVER_START_REQ( create_device )
604     {
605         req->access     = 0;
606         req->attributes = 0;
607         req->rootdir    = 0;
608         req->manager    = wine_server_obj_handle( manager );
609         req->user_ptr   = wine_server_client_ptr( device );
610         if (name) wine_server_add_data( req, name->Buffer, name->Length );
611         if (!(status = wine_server_call( req ))) handle = wine_server_ptr_handle( reply->handle );
612     }
613     SERVER_END_REQ;
614
615     if (status == STATUS_SUCCESS)
616     {
617         device->DriverObject    = driver;
618         device->DeviceExtension = device + 1;
619         device->DeviceType      = type;
620         device->StackSize       = 1;
621         device->Reserved        = handle;
622
623         device->NextDevice   = driver->DeviceObject;
624         driver->DeviceObject = device;
625
626         *ret_device = device;
627     }
628     else HeapFree( GetProcessHeap(), 0, device );
629
630     return status;
631 }
632
633
634 /***********************************************************************
635  *           IoDeleteDevice   (NTOSKRNL.EXE.@)
636  */
637 void WINAPI IoDeleteDevice( DEVICE_OBJECT *device )
638 {
639     NTSTATUS status;
640
641     TRACE( "%p\n", device );
642
643     SERVER_START_REQ( delete_device )
644     {
645         req->handle = wine_server_obj_handle( device->Reserved );
646         status = wine_server_call( req );
647     }
648     SERVER_END_REQ;
649
650     if (status == STATUS_SUCCESS)
651     {
652         DEVICE_OBJECT **prev = &device->DriverObject->DeviceObject;
653         while (*prev && *prev != device) prev = &(*prev)->NextDevice;
654         if (*prev) *prev = (*prev)->NextDevice;
655         NtClose( device->Reserved );
656         HeapFree( GetProcessHeap(), 0, device );
657     }
658 }
659
660
661 /***********************************************************************
662  *           IoCreateSymbolicLink   (NTOSKRNL.EXE.@)
663  */
664 NTSTATUS WINAPI IoCreateSymbolicLink( UNICODE_STRING *name, UNICODE_STRING *target )
665 {
666     HANDLE handle;
667     OBJECT_ATTRIBUTES attr;
668
669     attr.Length                   = sizeof(attr);
670     attr.RootDirectory            = 0;
671     attr.ObjectName               = name;
672     attr.Attributes               = OBJ_CASE_INSENSITIVE | OBJ_OPENIF;
673     attr.SecurityDescriptor       = NULL;
674     attr.SecurityQualityOfService = NULL;
675
676     TRACE( "%s -> %s\n", debugstr_us(name), debugstr_us(target) );
677     /* FIXME: store handle somewhere */
678     return NtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, target );
679 }
680
681
682 /***********************************************************************
683  *           IoDeleteSymbolicLink   (NTOSKRNL.EXE.@)
684  */
685 NTSTATUS WINAPI IoDeleteSymbolicLink( UNICODE_STRING *name )
686 {
687     HANDLE handle;
688     OBJECT_ATTRIBUTES attr;
689     NTSTATUS status;
690
691     attr.Length                   = sizeof(attr);
692     attr.RootDirectory            = 0;
693     attr.ObjectName               = name;
694     attr.Attributes               = OBJ_CASE_INSENSITIVE;
695     attr.SecurityDescriptor       = NULL;
696     attr.SecurityQualityOfService = NULL;
697
698     if (!(status = NtOpenSymbolicLinkObject( &handle, 0, &attr )))
699     {
700         SERVER_START_REQ( unlink_object )
701         {
702             req->handle = wine_server_obj_handle( handle );
703             status = wine_server_call( req );
704         }
705         SERVER_END_REQ;
706         NtClose( handle );
707     }
708     return status;
709 }
710
711
712 /***********************************************************************
713  *           IoGetDeviceInterfaces   (NTOSKRNL.EXE.@)
714  */
715 NTSTATUS WINAPI IoGetDeviceInterfaces( CONST GUID *InterfaceClassGuid,
716                                        PDEVICE_OBJECT PhysicalDeviceObject,
717                                        ULONG Flags, PWSTR *SymbolicLinkList )
718 {
719     FIXME( "stub: %s %p %x %p\n", debugstr_guid(InterfaceClassGuid),
720            PhysicalDeviceObject, Flags, SymbolicLinkList );
721     return STATUS_NOT_IMPLEMENTED;
722 }
723
724
725 /***********************************************************************
726  *           IoGetDeviceObjectPointer   (NTOSKRNL.EXE.@)
727  */
728 NTSTATUS  WINAPI IoGetDeviceObjectPointer( UNICODE_STRING *name, ACCESS_MASK access, PFILE_OBJECT *file, PDEVICE_OBJECT *device )
729 {
730     FIXME( "stub: %s %x %p %p\n", debugstr_us(name), access, file, device );
731
732     return STATUS_NOT_IMPLEMENTED;
733 }
734
735
736 /***********************************************************************
737  *           IoGetDeviceProperty   (NTOSKRNL.EXE.@)
738  */
739 NTSTATUS WINAPI IoGetDeviceProperty( DEVICE_OBJECT *device, DEVICE_REGISTRY_PROPERTY device_property,
740                                      ULONG buffer_length, PVOID property_buffer, PULONG result_length )
741 {
742     FIXME( "%p %d %u %p %p: stub\n", device, device_property, buffer_length,
743            property_buffer, result_length );
744     return STATUS_NOT_IMPLEMENTED;
745 }
746
747
748 /***********************************************************************
749  *           IoCallDriver   (NTOSKRNL.EXE.@)
750  */
751 NTSTATUS WINAPI IoCallDriver( DEVICE_OBJECT *device, IRP *irp )
752 {
753     PDRIVER_DISPATCH dispatch;
754     IO_STACK_LOCATION *irpsp;
755     NTSTATUS status;
756
757     TRACE( "%p %p\n", device, irp );
758
759     --irp->CurrentLocation;
760     irpsp = --irp->Tail.Overlay.s.u2.CurrentStackLocation;
761     dispatch = device->DriverObject->MajorFunction[irpsp->MajorFunction];
762     status = dispatch( device, irp );
763
764     return status;
765 }
766
767
768 /***********************************************************************
769  *           IofCallDriver   (NTOSKRNL.EXE.@)
770  */
771 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
772 DEFINE_FASTCALL2_ENTRYPOINT( IofCallDriver )
773 NTSTATUS WINAPI __regs_IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
774 #else
775 NTSTATUS WINAPI IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
776 #endif
777 {
778     TRACE( "%p %p\n", device, irp );
779     return IoCallDriver( device, irp );
780 }
781
782
783 /***********************************************************************
784  *           IoGetRelatedDeviceObject    (NTOSKRNL.EXE.@)
785  */
786 PDEVICE_OBJECT WINAPI IoGetRelatedDeviceObject( PFILE_OBJECT obj )
787 {
788     FIXME( "stub: %p\n", obj );
789     return NULL;
790 }
791
792 static CONFIGURATION_INFORMATION configuration_information;
793
794 /***********************************************************************
795  *           IoGetConfigurationInformation    (NTOSKRNL.EXE.@)
796  */
797 PCONFIGURATION_INFORMATION WINAPI IoGetConfigurationInformation(void)
798 {
799     FIXME( "partial stub\n" );
800     /* FIXME: return actual devices on system */
801     return &configuration_information;
802 }
803
804
805 /***********************************************************************
806  *           IoIsWdmVersionAvailable     (NTOSKRNL.EXE.@)
807  */
808 NTSTATUS WINAPI IoIsWdmVersionAvailable(UCHAR MajorVersion, UCHAR MinorVersion)
809 {
810     DWORD version;
811     DWORD major;
812     DWORD minor;
813
814     TRACE( "%d, 0x%X\n", MajorVersion, MinorVersion );
815
816     version = GetVersion();
817     major = LOBYTE(version);
818     minor = HIBYTE(LOWORD(version));
819
820     if (MajorVersion == 6 && MinorVersion == 0)
821     {
822         /* Windows Vista, Windows Server 2008, Windows 7 */
823     }
824     else if (MajorVersion == 1)
825     {
826         if (MinorVersion == 0x30)
827         {
828             /* Windows server 2003 */
829             MajorVersion = 6;
830             MinorVersion = 0;
831         }
832         else if (MinorVersion == 0x20)
833         {
834             /* Windows XP */
835             MajorVersion = 5;
836             MinorVersion = 1;
837         }
838         else if (MinorVersion == 0x10)
839         {
840             /* Windows 2000 */
841             MajorVersion = 5;
842             MinorVersion = 0;
843         }
844         else if (MinorVersion == 0x05)
845         {
846             /* Windows ME */
847             MajorVersion = 4;
848             MinorVersion = 0x5a;
849         }
850         else if (MinorVersion == 0x00)
851         {
852             /* Windows 98 */
853             MajorVersion = 4;
854             MinorVersion = 0x0a;
855         }
856         else
857         {
858             FIXME( "unknown major %d minor 0x%X\n", MajorVersion, MinorVersion );
859             return FALSE;
860         }
861     }
862     else
863     {
864         FIXME( "unknown major %d minor 0x%X\n", MajorVersion, MinorVersion );
865         return FALSE;
866     }
867     return major > MajorVersion || (major == MajorVersion && minor >= MinorVersion);
868 }
869
870
871 /***********************************************************************
872  *           IoQueryDeviceDescription    (NTOSKRNL.EXE.@)
873  */
874 NTSTATUS WINAPI IoQueryDeviceDescription(PINTERFACE_TYPE itype, PULONG bus, PCONFIGURATION_TYPE ctype,
875                                      PULONG cnum, PCONFIGURATION_TYPE ptype, PULONG pnum,
876                                      PIO_QUERY_DEVICE_ROUTINE callout, PVOID context)
877 {
878     FIXME( "(%p %p %p %p %p %p %p %p)\n", itype, bus, ctype, cnum, ptype, pnum, callout, context);
879     return STATUS_NOT_IMPLEMENTED;
880 }
881
882
883 /***********************************************************************
884  *           IoRegisterDriverReinitialization    (NTOSKRNL.EXE.@)
885  */
886 void WINAPI IoRegisterDriverReinitialization( PDRIVER_OBJECT obj, PDRIVER_REINITIALIZE reinit, PVOID context )
887 {
888     FIXME( "stub: %p %p %p\n", obj, reinit, context );
889 }
890
891
892 /***********************************************************************
893  *           IoRegisterShutdownNotification    (NTOSKRNL.EXE.@)
894  */
895 NTSTATUS WINAPI IoRegisterShutdownNotification( PDEVICE_OBJECT obj )
896 {
897     FIXME( "stub: %p\n", obj );
898     return STATUS_SUCCESS;
899 }
900
901
902 /***********************************************************************
903  *           IoUnregisterShutdownNotification    (NTOSKRNL.EXE.@)
904  */
905 VOID WINAPI IoUnregisterShutdownNotification( PDEVICE_OBJECT obj )
906 {
907     FIXME( "stub: %p\n", obj );
908 }
909
910
911 /***********************************************************************
912  *           IoReportResourceUsage    (NTOSKRNL.EXE.@)
913  */
914 NTSTATUS WINAPI IoReportResourceUsage(PUNICODE_STRING name, PDRIVER_OBJECT drv_obj, PCM_RESOURCE_LIST drv_list,
915                                       ULONG drv_size, PDRIVER_OBJECT dev_obj, PCM_RESOURCE_LIST dev_list,
916                                       ULONG dev_size, BOOLEAN overwrite, PBOOLEAN detected)
917 {
918     FIXME("(%s %p %p %u %p %p %u %d %p) stub\n", debugstr_w(name? name->Buffer : NULL),
919           drv_obj, drv_list, drv_size, dev_obj, dev_list, dev_size, overwrite, detected);
920     return STATUS_NOT_IMPLEMENTED;
921 }
922
923
924 /***********************************************************************
925  *           IoCompleteRequest   (NTOSKRNL.EXE.@)
926  */
927 VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
928 {
929     IO_STACK_LOCATION *irpsp;
930     PIO_COMPLETION_ROUTINE routine;
931     IO_STATUS_BLOCK *iosb;
932     struct IrpInstance *instance;
933     NTSTATUS status, stat;
934     int call_flag = 0;
935
936     TRACE( "%p %u\n", irp, priority_boost );
937
938     iosb = irp->UserIosb;
939     status = irp->IoStatus.u.Status;
940     while (irp->CurrentLocation <= irp->StackCount)
941     {
942         irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
943         routine = irpsp->CompletionRoutine;
944         call_flag = 0;
945         /* FIXME: add SL_INVOKE_ON_CANCEL support */
946         if (routine)
947         {
948             if ((irpsp->Control & SL_INVOKE_ON_SUCCESS) && STATUS_SUCCESS == status)
949                 call_flag = 1;
950             if ((irpsp->Control & SL_INVOKE_ON_ERROR) && STATUS_SUCCESS != status)
951                 call_flag = 1;
952         }
953         ++irp->CurrentLocation;
954         ++irp->Tail.Overlay.s.u2.CurrentStackLocation;
955         if (call_flag)
956         {
957             TRACE( "calling %p( %p, %p, %p )\n", routine,
958                     irpsp->DeviceObject, irp, irpsp->Context );
959             stat = routine( irpsp->DeviceObject, irp, irpsp->Context );
960             TRACE( "CompletionRoutine returned %x\n", stat );
961             if (STATUS_MORE_PROCESSING_REQUIRED == stat)
962                 return;
963         }
964     }
965     if (iosb && STATUS_SUCCESS == status)
966     {
967         iosb->u.Status = irp->IoStatus.u.Status;
968         iosb->Information = irp->IoStatus.Information;
969     }
970     LIST_FOR_EACH_ENTRY( instance, &Irps, struct IrpInstance, entry )
971     {
972         if (instance->irp == irp)
973         {
974             list_remove( &instance->entry );
975             HeapFree( GetProcessHeap(), 0, instance );
976             IoFreeIrp( irp );
977             break;
978         }
979     }
980 }
981
982
983 /***********************************************************************
984  *           IofCompleteRequest   (NTOSKRNL.EXE.@)
985  */
986 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
987 DEFINE_FASTCALL2_ENTRYPOINT( IofCompleteRequest )
988 void WINAPI __regs_IofCompleteRequest( IRP *irp, UCHAR priority_boost )
989 #else
990 void WINAPI IofCompleteRequest( IRP *irp, UCHAR priority_boost )
991 #endif
992 {
993     TRACE( "%p %u\n", irp, priority_boost );
994     IoCompleteRequest( irp, priority_boost );
995 }
996
997
998 /***********************************************************************
999  *           InterlockedCompareExchange   (NTOSKRNL.EXE.@)
1000  */
1001 #ifdef DEFINE_FASTCALL3_ENTRYPOINT
1002 DEFINE_FASTCALL3_ENTRYPOINT( NTOSKRNL_InterlockedCompareExchange )
1003 LONG WINAPI __regs_NTOSKRNL_InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
1004 #else
1005 LONG WINAPI NTOSKRNL_InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
1006 #endif
1007 {
1008     return InterlockedCompareExchange( dest, xchg, compare );
1009 }
1010
1011
1012 /***********************************************************************
1013  *           InterlockedDecrement   (NTOSKRNL.EXE.@)
1014  */
1015 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1016 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedDecrement )
1017 LONG WINAPI __regs_NTOSKRNL_InterlockedDecrement( LONG volatile *dest )
1018 #else
1019 LONG WINAPI NTOSKRNL_InterlockedDecrement( LONG volatile *dest )
1020 #endif
1021 {
1022     return InterlockedDecrement( dest );
1023 }
1024
1025
1026 /***********************************************************************
1027  *           InterlockedExchange   (NTOSKRNL.EXE.@)
1028  */
1029 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1030 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchange )
1031 LONG WINAPI __regs_NTOSKRNL_InterlockedExchange( LONG volatile *dest, LONG val )
1032 #else
1033 LONG WINAPI NTOSKRNL_InterlockedExchange( LONG volatile *dest, LONG val )
1034 #endif
1035 {
1036     return InterlockedExchange( dest, val );
1037 }
1038
1039
1040 /***********************************************************************
1041  *           InterlockedExchangeAdd   (NTOSKRNL.EXE.@)
1042  */
1043 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1044 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchangeAdd )
1045 LONG WINAPI __regs_NTOSKRNL_InterlockedExchangeAdd( LONG volatile *dest, LONG incr )
1046 #else
1047 LONG WINAPI NTOSKRNL_InterlockedExchangeAdd( LONG volatile *dest, LONG incr )
1048 #endif
1049 {
1050     return InterlockedExchangeAdd( dest, incr );
1051 }
1052
1053
1054 /***********************************************************************
1055  *           InterlockedIncrement   (NTOSKRNL.EXE.@)
1056  */
1057 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1058 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedIncrement )
1059 LONG WINAPI __regs_NTOSKRNL_InterlockedIncrement( LONG volatile *dest )
1060 #else
1061 LONG WINAPI NTOSKRNL_InterlockedIncrement( LONG volatile *dest )
1062 #endif
1063 {
1064     return InterlockedIncrement( dest );
1065 }
1066
1067
1068 /***********************************************************************
1069  *           ExAllocatePool   (NTOSKRNL.EXE.@)
1070  */
1071 PVOID WINAPI ExAllocatePool( POOL_TYPE type, SIZE_T size )
1072 {
1073     return ExAllocatePoolWithTag( type, size, 0 );
1074 }
1075
1076
1077 /***********************************************************************
1078  *           ExAllocatePoolWithQuota   (NTOSKRNL.EXE.@)
1079  */
1080 PVOID WINAPI ExAllocatePoolWithQuota( POOL_TYPE type, SIZE_T size )
1081 {
1082     return ExAllocatePoolWithTag( type, size, 0 );
1083 }
1084
1085
1086 /***********************************************************************
1087  *           ExAllocatePoolWithTag   (NTOSKRNL.EXE.@)
1088  */
1089 PVOID WINAPI ExAllocatePoolWithTag( POOL_TYPE type, SIZE_T size, ULONG tag )
1090 {
1091     /* FIXME: handle page alignment constraints */
1092     void *ret = HeapAlloc( GetProcessHeap(), 0, size );
1093     TRACE( "%lu pool %u -> %p\n", size, type, ret );
1094     return ret;
1095 }
1096
1097
1098 /***********************************************************************
1099  *           ExAllocatePoolWithQuotaTag   (NTOSKRNL.EXE.@)
1100  */
1101 PVOID WINAPI ExAllocatePoolWithQuotaTag( POOL_TYPE type, SIZE_T size, ULONG tag )
1102 {
1103     return ExAllocatePoolWithTag( type, size, tag );
1104 }
1105
1106
1107 /***********************************************************************
1108  *           ExCreateCallback   (NTOSKRNL.EXE.@)
1109  */
1110 NTSTATUS WINAPI ExCreateCallback(PCALLBACK_OBJECT *obj, POBJECT_ATTRIBUTES attr,
1111                                  BOOLEAN create, BOOLEAN allow_multiple)
1112 {
1113     FIXME("(%p, %p, %u, %u): stub\n", obj, attr, create, allow_multiple);
1114
1115     return STATUS_NOT_IMPLEMENTED;
1116 }
1117
1118
1119 /***********************************************************************
1120  *           ExFreePool   (NTOSKRNL.EXE.@)
1121  */
1122 void WINAPI ExFreePool( void *ptr )
1123 {
1124     ExFreePoolWithTag( ptr, 0 );
1125 }
1126
1127
1128 /***********************************************************************
1129  *           ExFreePoolWithTag   (NTOSKRNL.EXE.@)
1130  */
1131 void WINAPI ExFreePoolWithTag( void *ptr, ULONG tag )
1132 {
1133     TRACE( "%p\n", ptr );
1134     HeapFree( GetProcessHeap(), 0, ptr );
1135 }
1136
1137
1138 /***********************************************************************
1139  *           ExInitializeResourceLite   (NTOSKRNL.EXE.@)
1140  */
1141 NTSTATUS WINAPI ExInitializeResourceLite(PERESOURCE Resource)
1142 {
1143     FIXME( "stub: %p\n", Resource );
1144     return STATUS_NOT_IMPLEMENTED;
1145 }
1146
1147
1148 /***********************************************************************
1149  *           ExInitializeNPagedLookasideList   (NTOSKRNL.EXE.@)
1150  */
1151 void WINAPI ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside,
1152                                             PALLOCATE_FUNCTION Allocate,
1153                                             PFREE_FUNCTION Free,
1154                                             ULONG Flags,
1155                                             SIZE_T Size,
1156                                             ULONG Tag,
1157                                             USHORT Depth)
1158 {
1159     FIXME( "stub: %p, %p, %p, %u, %lu, %u, %u\n", Lookaside, Allocate, Free, Flags, Size, Tag, Depth );
1160 }
1161
1162 /***********************************************************************
1163  *           ExInitializePagedLookasideList   (NTOSKRNL.EXE.@)
1164  */
1165 void WINAPI ExInitializePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside,
1166                                            PALLOCATE_FUNCTION Allocate,
1167                                            PFREE_FUNCTION Free,
1168                                            ULONG Flags,
1169                                            SIZE_T Size,
1170                                            ULONG Tag,
1171                                            USHORT Depth)
1172 {
1173     FIXME( "stub: %p, %p, %p, %u, %lu, %u, %u\n", Lookaside, Allocate, Free, Flags, Size, Tag, Depth );
1174 }
1175
1176 /***********************************************************************
1177  *           ExInitializeZone   (NTOSKRNL.EXE.@)
1178  */
1179 NTSTATUS WINAPI ExInitializeZone(PZONE_HEADER Zone,
1180                                  ULONG BlockSize,
1181                                  PVOID InitialSegment,
1182                                  ULONG InitialSegmentSize)
1183 {
1184     FIXME( "stub: %p, %u, %p, %u\n", Zone, BlockSize, InitialSegment, InitialSegmentSize );
1185     return STATUS_NOT_IMPLEMENTED;
1186 }
1187
1188 /***********************************************************************
1189 *           FsRtlRegisterUncProvider   (NTOSKRNL.EXE.@)
1190 */
1191 NTSTATUS WINAPI FsRtlRegisterUncProvider(PHANDLE MupHandle, PUNICODE_STRING RedirDevName,
1192                                          BOOLEAN MailslotsSupported)
1193 {
1194     FIXME("(%p %p %d): stub\n", MupHandle, RedirDevName, MailslotsSupported);
1195     return STATUS_NOT_IMPLEMENTED;
1196 }
1197
1198 /***********************************************************************
1199  *           IoGetCurrentProcess / PsGetCurrentProcess   (NTOSKRNL.EXE.@)
1200  */
1201 PEPROCESS WINAPI IoGetCurrentProcess(void)
1202 {
1203     FIXME("() stub\n");
1204     return NULL;
1205 }
1206
1207 /***********************************************************************
1208  *           KeGetCurrentThread / PsGetCurrentThread   (NTOSKRNL.EXE.@)
1209  */
1210 PRKTHREAD WINAPI KeGetCurrentThread(void)
1211 {
1212     FIXME("() stub\n");
1213     return NULL;
1214 }
1215
1216 /***********************************************************************
1217  *           KeInitializeEvent   (NTOSKRNL.EXE.@)
1218  */
1219 void WINAPI KeInitializeEvent( PRKEVENT Event, EVENT_TYPE Type, BOOLEAN State )
1220 {
1221     FIXME( "stub: %p %d %d\n", Event, Type, State );
1222 }
1223
1224
1225  /***********************************************************************
1226  *           KeInitializeMutex   (NTOSKRNL.EXE.@)
1227  */
1228 void WINAPI KeInitializeMutex(PRKMUTEX Mutex, ULONG Level)
1229 {
1230     FIXME( "stub: %p, %u\n", Mutex, Level );
1231 }
1232
1233
1234  /***********************************************************************
1235  *           KeWaitForMutexObject   (NTOSKRNL.EXE.@)
1236  */
1237 NTSTATUS WINAPI KeWaitForMutexObject(PRKMUTEX Mutex, KWAIT_REASON WaitReason, KPROCESSOR_MODE WaitMode,
1238                                      BOOLEAN Alertable, PLARGE_INTEGER Timeout)
1239 {
1240     FIXME( "stub: %p, %d, %d, %d, %p\n", Mutex, WaitReason, WaitMode, Alertable, Timeout );
1241     return STATUS_NOT_IMPLEMENTED;
1242 }
1243
1244
1245  /***********************************************************************
1246  *           KeReleaseMutex   (NTOSKRNL.EXE.@)
1247  */
1248 LONG WINAPI KeReleaseMutex(PRKMUTEX Mutex, BOOLEAN Wait)
1249 {
1250     FIXME( "stub: %p, %d\n", Mutex, Wait );
1251     return STATUS_NOT_IMPLEMENTED;
1252 }
1253
1254
1255 /***********************************************************************
1256  *           KeInitializeSemaphore   (NTOSKRNL.EXE.@)
1257  */
1258 void WINAPI KeInitializeSemaphore( PRKSEMAPHORE Semaphore, LONG Count, LONG Limit )
1259 {
1260     FIXME( "(%p %d %d) stub\n", Semaphore , Count, Limit );
1261 }
1262
1263
1264 /***********************************************************************
1265  *           KeInitializeSpinLock   (NTOSKRNL.EXE.@)
1266  */
1267 void WINAPI KeInitializeSpinLock( PKSPIN_LOCK SpinLock )
1268 {
1269     FIXME( "stub: %p\n", SpinLock );
1270 }
1271
1272
1273 /***********************************************************************
1274  *           KeInitializeTimerEx   (NTOSKRNL.EXE.@)
1275  */
1276 void WINAPI KeInitializeTimerEx( PKTIMER Timer, TIMER_TYPE Type )
1277 {
1278     FIXME( "stub: %p %d\n", Timer, Type );
1279 }
1280
1281
1282 /***********************************************************************
1283  *           KeInitializeTimer   (NTOSKRNL.EXE.@)
1284  */
1285 void WINAPI KeInitializeTimer( PKTIMER Timer )
1286 {
1287     KeInitializeTimerEx(Timer, NotificationTimer);
1288 }
1289
1290
1291 /**********************************************************************
1292  *           KeQueryActiveProcessors   (NTOSKRNL.EXE.@)
1293  *
1294  * Return the active Processors as bitmask
1295  *
1296  * RETURNS
1297  *   active Processors as bitmask
1298  *
1299  */
1300 KAFFINITY WINAPI KeQueryActiveProcessors( void )
1301 {
1302     DWORD_PTR AffinityMask;
1303
1304     GetProcessAffinityMask( GetCurrentProcess(), &AffinityMask, NULL);
1305     return AffinityMask;
1306 }
1307
1308
1309 /**********************************************************************
1310  *           KeQueryInterruptTime   (NTOSKRNL.EXE.@)
1311  *
1312  * Return the interrupt time count
1313  *
1314  */
1315 ULONGLONG WINAPI KeQueryInterruptTime( void )
1316 {
1317     LARGE_INTEGER totaltime;
1318
1319     KeQueryTickCount(&totaltime);
1320     return totaltime.QuadPart;
1321 }
1322
1323
1324 /***********************************************************************
1325  *           KeQuerySystemTime   (NTOSKRNL.EXE.@)
1326  */
1327 void WINAPI KeQuerySystemTime( LARGE_INTEGER *time )
1328 {
1329     NtQuerySystemTime( time );
1330 }
1331
1332
1333 /***********************************************************************
1334  *           KeQueryTickCount   (NTOSKRNL.EXE.@)
1335  */
1336 void WINAPI KeQueryTickCount( LARGE_INTEGER *count )
1337 {
1338     count->QuadPart = NtGetTickCount();
1339     /* update the global variable too */
1340     KeTickCount.LowPart   = count->u.LowPart;
1341     KeTickCount.High1Time = count->u.HighPart;
1342     KeTickCount.High2Time = count->u.HighPart;
1343 }
1344
1345
1346 /***********************************************************************
1347  *           KeReleaseSemaphore   (NTOSKRNL.EXE.@)
1348  */
1349 LONG WINAPI KeReleaseSemaphore( PRKSEMAPHORE Semaphore, KPRIORITY Increment,
1350                                 LONG Adjustment, BOOLEAN Wait )
1351 {
1352     FIXME("(%p %d %d %d) stub\n", Semaphore, Increment, Adjustment, Wait );
1353     return 0;
1354 }
1355
1356
1357 /***********************************************************************
1358  *           KeQueryTimeIncrement   (NTOSKRNL.EXE.@)
1359  */
1360 ULONG WINAPI KeQueryTimeIncrement(void)
1361 {
1362     return 10000;
1363 }
1364
1365
1366 /***********************************************************************
1367  *           KeResetEvent   (NTOSKRNL.EXE.@)
1368  */
1369 LONG WINAPI KeResetEvent( PRKEVENT Event )
1370 {
1371     FIXME("(%p): stub\n", Event);
1372     return 0;
1373 }
1374
1375
1376 /***********************************************************************
1377  *           KeSetEvent   (NTOSKRNL.EXE.@)
1378  */
1379 LONG WINAPI KeSetEvent( PRKEVENT Event, KPRIORITY Increment, BOOLEAN Wait )
1380 {
1381     FIXME("(%p, %d, %d): stub\n", Event, Increment, Wait);
1382     return 0;
1383 }
1384
1385
1386 /***********************************************************************
1387  *           KeSetPriorityThread   (NTOSKRNL.EXE.@)
1388  */
1389 KPRIORITY WINAPI KeSetPriorityThread( PKTHREAD Thread, KPRIORITY Priority )
1390 {
1391     FIXME("(%p %d)\n", Thread, Priority);
1392     return Priority;
1393 }
1394
1395
1396 /***********************************************************************
1397  *           KeWaitForSingleObject   (NTOSKRNL.EXE.@)
1398  */
1399 NTSTATUS WINAPI KeWaitForSingleObject(PVOID Object,
1400                                       KWAIT_REASON WaitReason,
1401                                       KPROCESSOR_MODE WaitMode,
1402                                       BOOLEAN Alertable,
1403                                       PLARGE_INTEGER Timeout)
1404 {
1405     FIXME( "stub: %p, %d, %d, %d, %p\n", Object, WaitReason, WaitMode, Alertable, Timeout );
1406     return STATUS_NOT_IMPLEMENTED;
1407 }
1408
1409 /***********************************************************************
1410  *           IoRegisterFileSystem   (NTOSKRNL.EXE.@)
1411  */
1412 VOID WINAPI IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject)
1413 {
1414     FIXME("(%p): stub\n", DeviceObject);
1415 }
1416
1417 /***********************************************************************
1418 *           IoUnregisterFileSystem   (NTOSKRNL.EXE.@)
1419 */
1420 VOID WINAPI IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject)
1421 {
1422     FIXME("(%p): stub\n", DeviceObject);
1423 }
1424
1425 /***********************************************************************
1426  *           MmAllocateNonCachedMemory   (NTOSKRNL.EXE.@)
1427  */
1428 PVOID WINAPI MmAllocateNonCachedMemory( SIZE_T size )
1429 {
1430     TRACE( "%lu\n", size );
1431     return VirtualAlloc( NULL, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE|PAGE_NOCACHE );
1432 }
1433
1434 /***********************************************************************
1435  *           MmAllocateContiguousMemory   (NTOSKRNL.EXE.@)
1436  */
1437 PVOID WINAPI MmAllocateContiguousMemory( SIZE_T size, PHYSICAL_ADDRESS highest_valid_address )
1438 {
1439     FIXME( "%lu, %s stub\n", size, wine_dbgstr_longlong(highest_valid_address.QuadPart) );
1440     return NULL;
1441 }
1442
1443 /***********************************************************************
1444  *           MmAllocateContiguousMemorySpecifyCache   (NTOSKRNL.EXE.@)
1445  */
1446 PVOID WINAPI MmAllocateContiguousMemorySpecifyCache( SIZE_T size,
1447                                                      PHYSICAL_ADDRESS lowest_valid_address,
1448                                                      PHYSICAL_ADDRESS highest_valid_address,
1449                                                      PHYSICAL_ADDRESS BoundaryAddressMultiple,
1450                                                      MEMORY_CACHING_TYPE CacheType )
1451 {
1452     FIXME(": stub\n");
1453     return NULL;
1454 }
1455
1456 /***********************************************************************
1457  *           MmAllocatePagesForMdl   (NTOSKRNL.EXE.@)
1458  */
1459 PMDL WINAPI MmAllocatePagesForMdl(PHYSICAL_ADDRESS lowaddress, PHYSICAL_ADDRESS highaddress,
1460                                   PHYSICAL_ADDRESS skipbytes, SIZE_T size)
1461 {
1462     FIXME("%s %s %s %lu: stub\n", wine_dbgstr_longlong(lowaddress.QuadPart), wine_dbgstr_longlong(highaddress.QuadPart),
1463                                   wine_dbgstr_longlong(skipbytes.QuadPart), size);
1464     return NULL;
1465 }
1466
1467 /***********************************************************************
1468  *           MmFreeNonCachedMemory   (NTOSKRNL.EXE.@)
1469  */
1470 void WINAPI MmFreeNonCachedMemory( void *addr, SIZE_T size )
1471 {
1472     TRACE( "%p %lu\n", addr, size );
1473     VirtualFree( addr, 0, MEM_RELEASE );
1474 }
1475
1476 /***********************************************************************
1477  *           MmIsAddressValid   (NTOSKRNL.EXE.@)
1478  *
1479  * Check if the process can access the virtual address without a pagefault
1480  *
1481  * PARAMS
1482  *  VirtualAddress [I] Address to check
1483  *
1484  * RETURNS
1485  *  Failure: FALSE
1486  *  Success: TRUE  (Accessing the Address works without a Pagefault)
1487  *
1488  */
1489 BOOLEAN WINAPI MmIsAddressValid(PVOID VirtualAddress)
1490 {
1491     TRACE("(%p)\n", VirtualAddress);
1492     return !IsBadWritePtr(VirtualAddress, 1);
1493 }
1494
1495 /***********************************************************************
1496  *           MmMapIoSpace   (NTOSKRNL.EXE.@)
1497  */
1498 PVOID WINAPI MmMapIoSpace( PHYSICAL_ADDRESS PhysicalAddress, DWORD NumberOfBytes, DWORD CacheType )
1499 {
1500     FIXME( "stub: 0x%08x%08x, %d, %d\n", PhysicalAddress.u.HighPart, PhysicalAddress.u.LowPart, NumberOfBytes, CacheType );
1501     return NULL;
1502 }
1503
1504
1505 /***********************************************************************
1506  *           MmMapLockedPagesSpecifyCache  (NTOSKRNL.EXE.@)
1507  */
1508 PVOID WINAPI  MmMapLockedPagesSpecifyCache(PMDLX MemoryDescriptorList, KPROCESSOR_MODE AccessMode, MEMORY_CACHING_TYPE CacheType,
1509                                            PVOID BaseAddress, ULONG BugCheckOnFailure, MM_PAGE_PRIORITY Priority)
1510 {
1511     FIXME("(%p, %u, %u, %p, %u, %u): stub\n", MemoryDescriptorList, AccessMode, CacheType, BaseAddress, BugCheckOnFailure, Priority);
1512
1513     return NULL;
1514 }
1515
1516
1517 /***********************************************************************
1518  *           MmPageEntireDriver   (NTOSKRNL.EXE.@)
1519  */
1520 PVOID WINAPI MmPageEntireDriver(PVOID AddrInSection)
1521 {
1522     TRACE("%p\n", AddrInSection);
1523     return AddrInSection;
1524 }
1525
1526
1527 /***********************************************************************
1528  *           MmProbeAndLockPages  (NTOSKRNL.EXE.@)
1529  */
1530 void WINAPI MmProbeAndLockPages(PMDLX MemoryDescriptorList, KPROCESSOR_MODE AccessMode, LOCK_OPERATION Operation)
1531 {
1532     FIXME("(%p, %u, %u): stub\n", MemoryDescriptorList, AccessMode, Operation);
1533 }
1534
1535
1536 /***********************************************************************
1537  *           MmResetDriverPaging   (NTOSKRNL.EXE.@)
1538  */
1539 void WINAPI MmResetDriverPaging(PVOID AddrInSection)
1540 {
1541     TRACE("%p\n", AddrInSection);
1542 }
1543
1544
1545 /***********************************************************************
1546  *           MmUnlockPages  (NTOSKRNL.EXE.@)
1547  */
1548 void WINAPI  MmUnlockPages(PMDLX MemoryDescriptorList)
1549 {
1550     FIXME("(%p): stub\n", MemoryDescriptorList);
1551 }
1552
1553
1554 /***********************************************************************
1555  *           MmUnmapIoSpace   (NTOSKRNL.EXE.@)
1556  */
1557 VOID WINAPI MmUnmapIoSpace( PVOID BaseAddress, SIZE_T NumberOfBytes )
1558 {
1559     FIXME( "stub: %p, %lu\n", BaseAddress, NumberOfBytes );
1560 }
1561
1562 /***********************************************************************
1563  *           ObfReferenceObject   (NTOSKRNL.EXE.@)
1564  */
1565 VOID WINAPI ObfReferenceObject(PVOID Object)
1566 {
1567     FIXME("(%p): stub\n", Object);
1568 }
1569
1570  /***********************************************************************
1571  *           ObReferenceObjectByHandle    (NTOSKRNL.EXE.@)
1572  */
1573 NTSTATUS WINAPI ObReferenceObjectByHandle( HANDLE obj, ACCESS_MASK access,
1574                                            POBJECT_TYPE type,
1575                                            KPROCESSOR_MODE mode, PVOID* ptr,
1576                                            POBJECT_HANDLE_INFORMATION info)
1577 {
1578     FIXME( "stub: %p %x %p %d %p %p\n", obj, access, type, mode, ptr, info);
1579     return STATUS_NOT_IMPLEMENTED;
1580 }
1581
1582  /***********************************************************************
1583  *           ObReferenceObjectByName    (NTOSKRNL.EXE.@)
1584  */
1585 NTSTATUS WINAPI ObReferenceObjectByName( UNICODE_STRING *ObjectName,
1586                                          ULONG Attributes,
1587                                          ACCESS_STATE *AccessState,
1588                                          ACCESS_MASK DesiredAccess,
1589                                          POBJECT_TYPE ObjectType,
1590                                          KPROCESSOR_MODE AccessMode,
1591                                          void *ParseContext,
1592                                          void **Object)
1593 {
1594     FIXME("stub\n");
1595     return STATUS_NOT_IMPLEMENTED;
1596 }
1597
1598 /***********************************************************************
1599  *           ObfDereferenceObject   (NTOSKRNL.EXE.@)
1600  */
1601 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1602 DEFINE_FASTCALL1_ENTRYPOINT( ObfDereferenceObject )
1603 void WINAPI __regs_ObfDereferenceObject( VOID *obj )
1604 #else
1605 void WINAPI ObfDereferenceObject( VOID *obj )
1606 #endif
1607 {
1608     FIXME( "stub: %p\n", obj );
1609 }
1610
1611
1612 /***********************************************************************
1613  *           PsCreateSystemThread   (NTOSKRNL.EXE.@)
1614  */
1615 NTSTATUS WINAPI PsCreateSystemThread(PHANDLE ThreadHandle, ULONG DesiredAccess,
1616                                      POBJECT_ATTRIBUTES ObjectAttributes,
1617                                      HANDLE ProcessHandle, PCLIENT_ID ClientId,
1618                                      PKSTART_ROUTINE StartRoutine, PVOID StartContext)
1619 {
1620     if (!ProcessHandle) ProcessHandle = GetCurrentProcess();
1621     return RtlCreateUserThread(ProcessHandle, 0, FALSE, 0, 0,
1622                                0, StartRoutine, StartContext,
1623                                ThreadHandle, ClientId);
1624 }
1625
1626 /***********************************************************************
1627  *           PsGetCurrentProcessId   (NTOSKRNL.EXE.@)
1628  */
1629 HANDLE WINAPI PsGetCurrentProcessId(void)
1630 {
1631     if (GetCurrentThreadId() == request_thread)
1632         return UlongToHandle(client_pid);
1633     return UlongToHandle(GetCurrentProcessId());
1634 }
1635
1636
1637 /***********************************************************************
1638  *           PsGetCurrentThreadId   (NTOSKRNL.EXE.@)
1639  */
1640 HANDLE WINAPI PsGetCurrentThreadId(void)
1641 {
1642     if (GetCurrentThreadId() == request_thread)
1643         return UlongToHandle(client_tid);
1644     return UlongToHandle(GetCurrentThreadId());
1645 }
1646
1647
1648 /***********************************************************************
1649  *           PsGetVersion   (NTOSKRNL.EXE.@)
1650  */
1651 BOOLEAN WINAPI PsGetVersion(ULONG *major, ULONG *minor, ULONG *build, UNICODE_STRING *version )
1652 {
1653     RTL_OSVERSIONINFOEXW info;
1654
1655     info.dwOSVersionInfoSize = sizeof(info);
1656     RtlGetVersion( &info );
1657     if (major) *major = info.dwMajorVersion;
1658     if (minor) *minor = info.dwMinorVersion;
1659     if (build) *build = info.dwBuildNumber;
1660
1661     if (version)
1662     {
1663 #if 0  /* FIXME: GameGuard passes an uninitialized pointer in version->Buffer */
1664         size_t len = min( strlenW(info.szCSDVersion)*sizeof(WCHAR), version->MaximumLength );
1665         memcpy( version->Buffer, info.szCSDVersion, len );
1666         if (len < version->MaximumLength) version->Buffer[len / sizeof(WCHAR)] = 0;
1667         version->Length = len;
1668 #endif
1669     }
1670     return TRUE;
1671 }
1672
1673
1674 /***********************************************************************
1675  *           PsImpersonateClient   (NTOSKRNL.EXE.@)
1676  */
1677 NTSTATUS WINAPI PsImpersonateClient(PETHREAD Thread, PACCESS_TOKEN Token, BOOLEAN CopyOnOpen,
1678                                     BOOLEAN EffectiveOnly, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1679 {
1680     FIXME("(%p, %p, %u, %u, %u): stub\n", Thread, Token, CopyOnOpen, EffectiveOnly, ImpersonationLevel);
1681
1682     return STATUS_NOT_IMPLEMENTED;
1683 }
1684
1685
1686 /***********************************************************************
1687  *           PsSetCreateProcessNotifyRoutine   (NTOSKRNL.EXE.@)
1688  */
1689 NTSTATUS WINAPI PsSetCreateProcessNotifyRoutine( PCREATE_PROCESS_NOTIFY_ROUTINE callback, BOOLEAN remove )
1690 {
1691     FIXME( "stub: %p %d\n", callback, remove );
1692     return STATUS_SUCCESS;
1693 }
1694
1695
1696 /***********************************************************************
1697  *           PsSetCreateThreadNotifyRoutine   (NTOSKRNL.EXE.@)
1698  */
1699 NTSTATUS WINAPI PsSetCreateThreadNotifyRoutine( PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine )
1700 {
1701     FIXME( "stub: %p\n", NotifyRoutine );
1702     return STATUS_SUCCESS;
1703 }
1704
1705
1706 /***********************************************************************
1707  *           PsTerminateSystemThread   (NTOSKRNL.EXE.@)
1708  */
1709 NTSTATUS WINAPI PsTerminateSystemThread(NTSTATUS ExitStatus)
1710 {
1711     FIXME( "stub: %u\n", ExitStatus );
1712     return STATUS_NOT_IMPLEMENTED;
1713 }
1714
1715
1716 /***********************************************************************
1717  *           MmGetSystemRoutineAddress   (NTOSKRNL.EXE.@)
1718  */
1719 PVOID WINAPI MmGetSystemRoutineAddress(PUNICODE_STRING SystemRoutineName)
1720 {
1721     HMODULE hMod;
1722     STRING routineNameA;
1723     PVOID pFunc = NULL;
1724
1725     static const WCHAR ntoskrnlW[] = {'n','t','o','s','k','r','n','l','.','e','x','e',0};
1726     static const WCHAR halW[] = {'h','a','l','.','d','l','l',0};
1727
1728     if (!SystemRoutineName) return NULL;
1729
1730     if (RtlUnicodeStringToAnsiString( &routineNameA, SystemRoutineName, TRUE ) == STATUS_SUCCESS)
1731     {
1732         /* We only support functions exported from ntoskrnl.exe or hal.dll */
1733         hMod = GetModuleHandleW( ntoskrnlW );
1734         pFunc = GetProcAddress( hMod, routineNameA.Buffer );
1735         if (!pFunc)
1736         {
1737            hMod = GetModuleHandleW( halW );
1738            if (hMod) pFunc = GetProcAddress( hMod, routineNameA.Buffer );
1739         }
1740         RtlFreeAnsiString( &routineNameA );
1741     }
1742
1743     if (pFunc)
1744         TRACE( "%s -> %p\n", debugstr_us(SystemRoutineName), pFunc );
1745     else
1746         FIXME( "%s not found\n", debugstr_us(SystemRoutineName) );
1747     return pFunc;
1748 }
1749
1750
1751 /***********************************************************************
1752  *           MmQuerySystemSize   (NTOSKRNL.EXE.@)
1753  */
1754 MM_SYSTEMSIZE WINAPI MmQuerySystemSize(void)
1755 {
1756     FIXME("stub\n");
1757     return MmLargeSystem;
1758 }
1759
1760 /***********************************************************************
1761  *           KeInitializeDpc   (NTOSKRNL.EXE.@)
1762  */
1763 VOID WINAPI KeInitializeDpc(PRKDPC Dpc, PKDEFERRED_ROUTINE DeferredRoutine, PVOID DeferredContext)
1764 {
1765     FIXME("stub\n");
1766 }
1767
1768 /***********************************************************************
1769  *           READ_REGISTER_BUFFER_UCHAR   (NTOSKRNL.EXE.@)
1770  */
1771 VOID WINAPI READ_REGISTER_BUFFER_UCHAR(PUCHAR Register, PUCHAR Buffer, ULONG Count)
1772 {
1773     FIXME("stub\n");
1774 }
1775
1776 /*****************************************************
1777  *           PoSetPowerState   (NTOSKRNL.EXE.@)
1778  */
1779 POWER_STATE WINAPI PoSetPowerState(PDEVICE_OBJECT DeviceObject, POWER_STATE_TYPE Type, POWER_STATE State)
1780 {
1781     FIXME("(%p %u %u) stub\n", DeviceObject, Type, State.DeviceState);
1782     return State;
1783 }
1784
1785 /*****************************************************
1786  *           IoWMIRegistrationControl   (NTOSKRNL.EXE.@)
1787  */
1788 NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT DeviceObject, ULONG Action)
1789 {
1790     FIXME("(%p %u) stub\n", DeviceObject, Action);
1791     return STATUS_SUCCESS;
1792 }
1793
1794 /*****************************************************
1795  *           PsSetLoadImageNotifyRoutine   (NTOSKRNL.EXE.@)
1796  */
1797 NTSTATUS WINAPI PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine)
1798 {
1799     FIXME("(%p) stub\n", routine);
1800     return STATUS_SUCCESS;
1801 }
1802
1803 /*****************************************************
1804  *           PsLookupProcessByProcessId  (NTOSKRNL.EXE.@)
1805  */
1806 NTSTATUS WINAPI PsLookupProcessByProcessId(HANDLE processid, PEPROCESS *process)
1807 {
1808     FIXME("(%p %p) stub\n", processid, process);
1809     return STATUS_NOT_IMPLEMENTED;
1810 }
1811
1812
1813 /*****************************************************
1814  *           IoSetThreadHardErrorMode  (NTOSKRNL.EXE.@)
1815  */
1816 BOOLEAN WINAPI IoSetThreadHardErrorMode(BOOLEAN EnableHardErrors)
1817 {
1818     FIXME("stub\n");
1819     return FALSE;
1820 }
1821
1822
1823 /*****************************************************
1824  *           IoInitializeRemoveLockEx  (NTOSKRNL.EXE.@)
1825  */
1826 VOID WINAPI IoInitializeRemoveLockEx(PIO_REMOVE_LOCK lock, ULONG tag,
1827                                      ULONG maxmin, ULONG high, ULONG size)
1828 {
1829     FIXME("(%p %u %u %u %u) stub\n", lock, tag, maxmin, high, size);
1830 }
1831
1832
1833 /*****************************************************
1834  *           IoAcquireRemoveLockEx  (NTOSKRNL.EXE.@)
1835  */
1836
1837 NTSTATUS WINAPI IoAcquireRemoveLockEx(PIO_REMOVE_LOCK lock, PVOID tag,
1838                                       LPCSTR file, ULONG line, ULONG lock_size)
1839 {
1840     FIXME("(%p, %p, %s, %u, %u): stub\n", lock, tag, debugstr_a(file), line, lock_size);
1841
1842     return STATUS_NOT_IMPLEMENTED;
1843 }
1844
1845
1846 /*****************************************************
1847  *           DllMain
1848  */
1849 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
1850 {
1851     static void *handler;
1852     LARGE_INTEGER count;
1853
1854     switch(reason)
1855     {
1856     case DLL_PROCESS_ATTACH:
1857         DisableThreadLibraryCalls( inst );
1858 #ifdef __i386__
1859         handler = RtlAddVectoredExceptionHandler( TRUE, vectored_handler );
1860 #endif
1861         KeQueryTickCount( &count );  /* initialize the global KeTickCount */
1862         break;
1863     case DLL_PROCESS_DETACH:
1864         RtlRemoveVectoredExceptionHandler( handler );
1865         break;
1866     }
1867     return TRUE;
1868 }
1869
1870 /*****************************************************
1871  *           Ke386IoSetAccessProcess  (NTOSKRNL.EXE.@)
1872  */
1873 BOOLEAN WINAPI Ke386IoSetAccessProcess(PEPROCESS *process, ULONG flag)
1874 {
1875     FIXME("(%p %d) stub\n", process, flag);
1876     return FALSE;
1877 }
1878
1879 /*****************************************************
1880  *           Ke386SetIoAccessMap  (NTOSKRNL.EXE.@)
1881  */
1882 BOOLEAN WINAPI Ke386SetIoAccessMap(ULONG flag, PVOID buffer)
1883 {
1884     FIXME("(%d %p) stub\n", flag, buffer);
1885     return FALSE;
1886 }
1887
1888 /*****************************************************
1889  *           IoCreateSynchronizationEvent (NTOSKRNL.EXE.@)
1890  */
1891 PKEVENT WINAPI IoCreateSynchronizationEvent(PUNICODE_STRING name, PHANDLE handle)
1892 {
1893     FIXME("(%p %p) stub\n", name, handle);
1894     return NULL;
1895 }
1896
1897 /*****************************************************
1898  *           IoStartNextPacket  (NTOSKRNL.EXE.@)
1899  */
1900 VOID WINAPI IoStartNextPacket(PDEVICE_OBJECT deviceobject, BOOLEAN cancelable)
1901 {
1902     FIXME("(%p %d) stub\n", deviceobject, cancelable);
1903 }