2 * ntoskrnl.exe implementation
4 * Copyright (C) 2007 Alexandre Julliard
5 * Copyright (C) 2010 Damjan Jovanovic
6 * Copyright (C) 2016 Sebastian Lackner
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
32 #define WIN32_NO_STATUS
39 #include "ddk/ntddk.h"
40 #include "ddk/ntifs.h"
42 #include "wine/unicode.h"
43 #include "wine/server.h"
44 #include "wine/debug.h"
46 #include "wine/rbtree.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl
);
49 WINE_DECLARE_DEBUG_CHANNEL(relay
);
51 BOOLEAN KdDebuggerEnabled
= FALSE
;
52 ULONG InitSafeBootMode
= 0;
54 extern LONG CALLBACK
vectored_handler( EXCEPTION_POINTERS
*ptrs
);
56 KSYSTEM_TIME KeTickCount
= { 0, 0, 0 };
58 typedef struct _KSERVICE_TABLE_DESCRIPTOR
64 } KSERVICE_TABLE_DESCRIPTOR
, *PKSERVICE_TABLE_DESCRIPTOR
;
66 KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable
[4] = { { 0 } };
68 typedef void (WINAPI
*PCREATE_PROCESS_NOTIFY_ROUTINE
)(HANDLE
,HANDLE
,BOOLEAN
);
69 typedef void (WINAPI
*PCREATE_THREAD_NOTIFY_ROUTINE
)(HANDLE
,HANDLE
,BOOLEAN
);
71 static const WCHAR servicesW
[] = {'\\','R','e','g','i','s','t','r','y',
72 '\\','M','a','c','h','i','n','e',
73 '\\','S','y','s','t','e','m',
74 '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
75 '\\','S','e','r','v','i','c','e','s',
78 /* tid of the thread running client request */
79 static DWORD request_thread
;
81 /* pid/tid of the client thread */
82 static DWORD client_tid
;
83 static DWORD client_pid
;
87 struct wine_rb_entry entry
;
89 DRIVER_OBJECT driver_obj
;
90 DRIVER_EXTENSION driver_extension
;
93 static struct wine_rb_tree wine_drivers
;
95 static CRITICAL_SECTION drivers_cs
;
96 static CRITICAL_SECTION_DEBUG critsect_debug
=
99 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
100 0, 0, { (DWORD_PTR
)(__FILE__
": drivers_cs") }
102 static CRITICAL_SECTION drivers_cs
= { &critsect_debug
, -1, 0, 0, 0, 0 };
104 static void *wine_drivers_rb_alloc( size_t size
)
106 return HeapAlloc( GetProcessHeap(), 0, size
);
109 static void *wine_drivers_rb_realloc( void *ptr
, size_t size
)
111 return HeapReAlloc( GetProcessHeap(), 0, ptr
, size
);
114 static void wine_drivers_rb_free( void *ptr
)
116 HeapFree( GetProcessHeap(), 0, ptr
);
119 static int wine_drivers_rb_compare( const void *key
, const struct wine_rb_entry
*entry
)
121 const struct wine_driver
*driver
= WINE_RB_ENTRY_VALUE( entry
, const struct wine_driver
, entry
);
122 const UNICODE_STRING
*k
= key
;
124 return RtlCompareUnicodeString( k
, &driver
->driver_obj
.DriverName
, FALSE
);
127 static const struct wine_rb_functions wine_drivers_rb_functions
=
129 wine_drivers_rb_alloc
,
130 wine_drivers_rb_realloc
,
131 wine_drivers_rb_free
,
132 wine_drivers_rb_compare
,
136 #define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
137 __ASM_STDCALL_FUNC( name, 4, \
141 "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(4))
142 #define DEFINE_FASTCALL2_ENTRYPOINT( name ) \
143 __ASM_STDCALL_FUNC( name, 8, \
148 "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(8))
149 #define DEFINE_FASTCALL3_ENTRYPOINT( name ) \
150 __ASM_STDCALL_FUNC( name, 12, \
155 "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(12))
158 static inline LPCSTR
debugstr_us( const UNICODE_STRING
*us
)
160 if (!us
) return "<null>";
161 return debugstr_wn( us
->Buffer
, us
->Length
/ sizeof(WCHAR
) );
164 static HANDLE
get_device_manager(void)
166 static HANDLE device_manager
;
167 HANDLE handle
= 0, ret
= device_manager
;
171 SERVER_START_REQ( create_device_manager
)
173 req
->access
= SYNCHRONIZE
;
175 if (!wine_server_call( req
)) handle
= wine_server_ptr_handle( reply
->handle
);
181 ERR( "failed to create the device manager\n" );
184 if (!(ret
= InterlockedCompareExchangePointer( &device_manager
, handle
, 0 )))
187 NtClose( handle
); /* somebody beat us to it */
192 static NTSTATUS
dispatch_irp( DEVICE_OBJECT
*device
, IRP
*irp
)
196 KeQueryTickCount( &count
); /* update the global KeTickCount */
198 device
->CurrentIrp
= irp
;
200 IoCallDriver( device
, irp
);
202 device
->CurrentIrp
= NULL
;
204 return STATUS_SUCCESS
;
207 /* process a create request for a given file */
208 static NTSTATUS
dispatch_create( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
209 ULONG out_size
, HANDLE irp_handle
)
212 IO_STACK_LOCATION
*irpsp
;
214 DEVICE_OBJECT
*device
= wine_server_get_ptr( params
->create
.device
);
216 if (!(file
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*file
) ))) return STATUS_NO_MEMORY
;
218 TRACE( "device %p -> file %p\n", device
, file
);
220 file
->Type
= 5; /* MSDN */
221 file
->Size
= sizeof(*file
);
222 file
->DeviceObject
= device
;
224 if (!(irp
= IoAllocateIrp( device
->StackSize
, FALSE
)))
226 HeapFree( GetProcessHeap(), 0, file
);
227 return STATUS_NO_MEMORY
;
230 irpsp
= IoGetNextIrpStackLocation( irp
);
231 irpsp
->MajorFunction
= IRP_MJ_CREATE
;
232 irpsp
->DeviceObject
= device
;
233 irpsp
->CompletionRoutine
= NULL
;
234 irpsp
->Parameters
.Create
.SecurityContext
= NULL
; /* FIXME */
235 irpsp
->Parameters
.Create
.Options
= params
->create
.options
;
236 irpsp
->Parameters
.Create
.ShareAccess
= params
->create
.sharing
;
237 irpsp
->Parameters
.Create
.FileAttributes
= 0;
238 irpsp
->Parameters
.Create
.EaLength
= 0;
240 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
241 irp
->RequestorMode
= UserMode
;
242 irp
->AssociatedIrp
.SystemBuffer
= NULL
;
243 irp
->UserBuffer
= NULL
;
244 irp
->UserIosb
= irp_handle
; /* note: we abuse UserIosb to store the server irp handle */
245 irp
->UserEvent
= NULL
;
247 if (device
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
]) return dispatch_irp( device
, irp
);
249 irp
->IoStatus
.u
.Status
= STATUS_SUCCESS
;
250 IoCompleteRequest( irp
, IO_NO_INCREMENT
);
251 return STATUS_SUCCESS
;
254 /* process a close request for a given file */
255 static NTSTATUS
dispatch_close( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
256 ULONG out_size
, HANDLE irp_handle
)
259 IO_STACK_LOCATION
*irpsp
;
260 DEVICE_OBJECT
*device
;
261 FILE_OBJECT
*file
= wine_server_get_ptr( params
->close
.file
);
263 if (!file
) return STATUS_INVALID_HANDLE
;
265 device
= file
->DeviceObject
;
267 TRACE( "device %p file %p\n", device
, file
);
269 if (!(irp
= IoAllocateIrp( device
->StackSize
, FALSE
)))
271 HeapFree( GetProcessHeap(), 0, file
);
272 return STATUS_NO_MEMORY
;
275 irpsp
= IoGetNextIrpStackLocation( irp
);
276 irpsp
->MajorFunction
= IRP_MJ_CLOSE
;
277 irpsp
->DeviceObject
= device
;
278 irpsp
->CompletionRoutine
= NULL
;
279 irpsp
->Parameters
.Create
.SecurityContext
= NULL
; /* FIXME */
280 irpsp
->Parameters
.Create
.Options
= params
->create
.options
;
281 irpsp
->Parameters
.Create
.ShareAccess
= params
->create
.sharing
;
282 irpsp
->Parameters
.Create
.FileAttributes
= 0;
283 irpsp
->Parameters
.Create
.EaLength
= 0;
285 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
286 irp
->RequestorMode
= UserMode
;
287 irp
->AssociatedIrp
.SystemBuffer
= NULL
;
288 irp
->UserBuffer
= NULL
;
289 irp
->UserIosb
= irp_handle
; /* note: we abuse UserIosb to store the server irp handle */
290 irp
->UserEvent
= NULL
;
292 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
])
294 irp
->IoStatus
.u
.Status
= STATUS_SUCCESS
;
295 IoCompleteRequest( irp
, IO_NO_INCREMENT
);
297 else dispatch_irp( device
, irp
);
299 HeapFree( GetProcessHeap(), 0, file
); /* FIXME: async close processing not supported */
300 return STATUS_SUCCESS
;
303 /* process a read request for a given device */
304 static NTSTATUS
dispatch_read( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
305 ULONG out_size
, HANDLE irp_handle
)
309 LARGE_INTEGER offset
;
310 IO_STACK_LOCATION
*irpsp
;
311 DEVICE_OBJECT
*device
;
312 FILE_OBJECT
*file
= wine_server_get_ptr( params
->read
.file
);
314 if (!file
) return STATUS_INVALID_HANDLE
;
316 device
= file
->DeviceObject
;
317 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_READ
]) return STATUS_NOT_SUPPORTED
;
319 TRACE( "device %p file %p size %u\n", device
, file
, out_size
);
321 if (!(out_buff
= HeapAlloc( GetProcessHeap(), 0, out_size
))) return STATUS_NO_MEMORY
;
323 offset
.QuadPart
= params
->read
.pos
;
325 /* note: we abuse UserIosb to store the server irp handle */
326 if (!(irp
= IoBuildSynchronousFsdRequest( IRP_MJ_READ
, device
, out_buff
, out_size
,
327 &offset
, NULL
, irp_handle
)))
329 HeapFree( GetProcessHeap(), 0, out_buff
);
330 return STATUS_NO_MEMORY
;
333 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
334 irp
->RequestorMode
= UserMode
;
336 irpsp
= IoGetNextIrpStackLocation( irp
);
337 irpsp
->Parameters
.Read
.Key
= params
->read
.key
;
339 return dispatch_irp( device
, irp
);
342 /* process a write request for a given device */
343 static NTSTATUS
dispatch_write( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
344 ULONG out_size
, HANDLE irp_handle
)
347 LARGE_INTEGER offset
;
348 IO_STACK_LOCATION
*irpsp
;
349 DEVICE_OBJECT
*device
;
350 FILE_OBJECT
*file
= wine_server_get_ptr( params
->write
.file
);
352 if (!file
) return STATUS_INVALID_HANDLE
;
354 device
= file
->DeviceObject
;
355 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_WRITE
]) return STATUS_NOT_SUPPORTED
;
357 TRACE( "device %p file %p size %u\n", device
, file
, in_size
);
359 offset
.QuadPart
= params
->write
.pos
;
361 /* note: we abuse UserIosb to store the server irp handle */
362 if (!(irp
= IoBuildSynchronousFsdRequest( IRP_MJ_WRITE
, device
, in_buff
, in_size
,
363 &offset
, NULL
, irp_handle
)))
364 return STATUS_NO_MEMORY
;
366 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
367 irp
->RequestorMode
= UserMode
;
369 irpsp
= IoGetNextIrpStackLocation( irp
);
370 irpsp
->Parameters
.Write
.Key
= params
->write
.key
;
372 return dispatch_irp( device
, irp
);
375 /* process a flush request for a given device */
376 static NTSTATUS
dispatch_flush( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
377 ULONG out_size
, HANDLE irp_handle
)
380 DEVICE_OBJECT
*device
;
381 FILE_OBJECT
*file
= wine_server_get_ptr( params
->flush
.file
);
383 if (!file
) return STATUS_INVALID_HANDLE
;
385 device
= file
->DeviceObject
;
386 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
]) return STATUS_NOT_SUPPORTED
;
388 TRACE( "device %p file %p\n", device
, file
);
390 /* note: we abuse UserIosb to store the server irp handle */
391 if (!(irp
= IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS
, device
, in_buff
, in_size
,
392 NULL
, NULL
, irp_handle
)))
393 return STATUS_NO_MEMORY
;
395 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
396 irp
->RequestorMode
= UserMode
;
398 return dispatch_irp( device
, irp
);
401 /* process an ioctl request for a given device */
402 static NTSTATUS
dispatch_ioctl( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
403 ULONG out_size
, HANDLE irp_handle
)
406 void *out_buff
= NULL
;
407 DEVICE_OBJECT
*device
;
408 FILE_OBJECT
*file
= wine_server_get_ptr( params
->ioctl
.file
);
410 if (!file
) return STATUS_INVALID_HANDLE
;
412 device
= file
->DeviceObject
;
413 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
]) return STATUS_NOT_SUPPORTED
;
415 TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n",
416 params
->ioctl
.code
, device
, file
, in_size
, out_size
);
418 if ((params
->ioctl
.code
& 3) == METHOD_BUFFERED
) out_size
= max( in_size
, out_size
);
422 if (!(out_buff
= HeapAlloc( GetProcessHeap(), 0, out_size
))) return STATUS_NO_MEMORY
;
423 if ((params
->ioctl
.code
& 3) == METHOD_BUFFERED
)
425 memcpy( out_buff
, in_buff
, in_size
);
430 /* note: we abuse UserIosb to store the server handle to the ioctl */
431 irp
= IoBuildDeviceIoControlRequest( params
->ioctl
.code
, device
, in_buff
, in_size
, out_buff
, out_size
,
432 FALSE
, NULL
, irp_handle
);
435 HeapFree( GetProcessHeap(), 0, out_buff
);
436 return STATUS_NO_MEMORY
;
439 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
440 irp
->RequestorMode
= UserMode
;
442 return dispatch_irp( device
, irp
);
445 typedef NTSTATUS (*dispatch_func
)( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
446 ULONG out_size
, HANDLE irp_handle
);
448 static const dispatch_func dispatch_funcs
[IRP_MJ_MAXIMUM_FUNCTION
+ 1] =
450 dispatch_create
, /* IRP_MJ_CREATE */
451 NULL
, /* IRP_MJ_CREATE_NAMED_PIPE */
452 dispatch_close
, /* IRP_MJ_CLOSE */
453 dispatch_read
, /* IRP_MJ_READ */
454 dispatch_write
, /* IRP_MJ_WRITE */
455 NULL
, /* IRP_MJ_QUERY_INFORMATION */
456 NULL
, /* IRP_MJ_SET_INFORMATION */
457 NULL
, /* IRP_MJ_QUERY_EA */
458 NULL
, /* IRP_MJ_SET_EA */
459 dispatch_flush
, /* IRP_MJ_FLUSH_BUFFERS */
460 NULL
, /* IRP_MJ_QUERY_VOLUME_INFORMATION */
461 NULL
, /* IRP_MJ_SET_VOLUME_INFORMATION */
462 NULL
, /* IRP_MJ_DIRECTORY_CONTROL */
463 NULL
, /* IRP_MJ_FILE_SYSTEM_CONTROL */
464 dispatch_ioctl
, /* IRP_MJ_DEVICE_CONTROL */
465 NULL
, /* IRP_MJ_INTERNAL_DEVICE_CONTROL */
466 NULL
, /* IRP_MJ_SHUTDOWN */
467 NULL
, /* IRP_MJ_LOCK_CONTROL */
468 NULL
, /* IRP_MJ_CLEANUP */
469 NULL
, /* IRP_MJ_CREATE_MAILSLOT */
470 NULL
, /* IRP_MJ_QUERY_SECURITY */
471 NULL
, /* IRP_MJ_SET_SECURITY */
472 NULL
, /* IRP_MJ_POWER */
473 NULL
, /* IRP_MJ_SYSTEM_CONTROL */
474 NULL
, /* IRP_MJ_DEVICE_CHANGE */
475 NULL
, /* IRP_MJ_QUERY_QUOTA */
476 NULL
, /* IRP_MJ_SET_QUOTA */
477 NULL
, /* IRP_MJ_PNP */
481 /***********************************************************************
482 * wine_ntoskrnl_main_loop (Not a Windows API)
484 NTSTATUS CDECL
wine_ntoskrnl_main_loop( HANDLE stop_event
)
486 HANDLE manager
= get_device_manager();
488 NTSTATUS status
= STATUS_SUCCESS
;
489 irp_params_t irp_params
;
491 ULONG in_size
= 4096, out_size
= 0;
494 request_thread
= GetCurrentThreadId();
496 if (!(in_buff
= HeapAlloc( GetProcessHeap(), 0, in_size
)))
498 ERR( "failed to allocate buffer\n" );
499 return STATUS_NO_MEMORY
;
502 handles
[0] = stop_event
;
503 handles
[1] = manager
;
507 SERVER_START_REQ( get_next_device_request
)
509 req
->manager
= wine_server_obj_handle( manager
);
510 req
->prev
= wine_server_obj_handle( irp
);
511 req
->status
= status
;
512 wine_server_set_reply( req
, in_buff
, in_size
);
513 if (!(status
= wine_server_call( req
)))
515 irp
= wine_server_ptr_handle( reply
->next
);
516 irp_params
= reply
->params
;
517 client_tid
= reply
->client_tid
;
518 client_pid
= reply
->client_pid
;
519 in_size
= reply
->in_size
;
520 out_size
= reply
->out_size
;
524 irp
= 0; /* no previous irp */
526 in_size
= reply
->in_size
;
534 if (irp_params
.major
> IRP_MJ_MAXIMUM_FUNCTION
|| !dispatch_funcs
[irp_params
.major
])
536 WARN( "unsupported request %u\n", irp_params
.major
);
537 status
= STATUS_NOT_SUPPORTED
;
540 status
= dispatch_funcs
[irp_params
.major
]( &irp_params
, in_buff
, in_size
, out_size
, irp
);
541 if (status
== STATUS_SUCCESS
) irp
= 0; /* status reported by IoCompleteRequest */
543 case STATUS_BUFFER_OVERFLOW
:
544 HeapFree( GetProcessHeap(), 0, in_buff
);
545 in_buff
= HeapAlloc( GetProcessHeap(), 0, in_size
);
546 /* restart with larger buffer */
551 DWORD ret
= WaitForMultipleObjectsEx( 2, handles
, FALSE
, INFINITE
, TRUE
);
552 if (ret
== WAIT_OBJECT_0
)
554 HeapFree( GetProcessHeap(), 0, in_buff
);
555 return STATUS_SUCCESS
;
557 if (ret
!= WAIT_IO_COMPLETION
) break;
565 /***********************************************************************
566 * IoAcquireCancelSpinLock (NTOSKRNL.EXE.@)
568 void WINAPI
IoAcquireCancelSpinLock(PKIRQL irql
)
570 FIXME("(%p): stub\n", irql
);
574 /***********************************************************************
575 * IoReleaseCancelSpinLock (NTOSKRNL.EXE.@)
577 void WINAPI
IoReleaseCancelSpinLock(PKIRQL irql
)
579 FIXME("(%p): stub\n", irql
);
583 /***********************************************************************
584 * IoAllocateDriverObjectExtension (NTOSKRNL.EXE.@)
586 NTSTATUS WINAPI
IoAllocateDriverObjectExtension( PDRIVER_OBJECT DriverObject
,
587 PVOID ClientIdentificationAddress
,
588 ULONG DriverObjectExtensionSize
,
589 PVOID
*DriverObjectExtension
)
591 FIXME( "stub: %p, %p, %u, %p\n", DriverObject
, ClientIdentificationAddress
,
592 DriverObjectExtensionSize
, DriverObjectExtension
);
593 return STATUS_NOT_IMPLEMENTED
;
597 /***********************************************************************
598 * IoGetDriverObjectExtension (NTOSKRNL.EXE.@)
600 PVOID WINAPI
IoGetDriverObjectExtension( PDRIVER_OBJECT DriverObject
,
601 PVOID ClientIdentificationAddress
)
603 FIXME( "stub: %p, %p\n", DriverObject
, ClientIdentificationAddress
);
608 /***********************************************************************
609 * IoInitializeIrp (NTOSKRNL.EXE.@)
611 void WINAPI
IoInitializeIrp( IRP
*irp
, USHORT size
, CCHAR stack_size
)
613 TRACE( "%p, %u, %d\n", irp
, size
, stack_size
);
615 RtlZeroMemory( irp
, size
);
617 irp
->Type
= IO_TYPE_IRP
;
619 InitializeListHead( &irp
->ThreadListEntry
);
620 irp
->StackCount
= stack_size
;
621 irp
->CurrentLocation
= stack_size
+ 1;
622 irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
=
623 (PIO_STACK_LOCATION
)(irp
+ 1) + stack_size
;
627 /***********************************************************************
628 * IoInitializeTimer (NTOSKRNL.EXE.@)
630 NTSTATUS WINAPI
IoInitializeTimer(PDEVICE_OBJECT DeviceObject
,
631 PIO_TIMER_ROUTINE TimerRoutine
,
634 FIXME( "stub: %p, %p, %p\n", DeviceObject
, TimerRoutine
, Context
);
635 return STATUS_NOT_IMPLEMENTED
;
639 /***********************************************************************
640 * IoStartTimer (NTOSKRNL.EXE.@)
642 void WINAPI
IoStartTimer(PDEVICE_OBJECT DeviceObject
)
644 FIXME( "stub: %p\n", DeviceObject
);
648 /***********************************************************************
649 * IoAllocateIrp (NTOSKRNL.EXE.@)
651 PIRP WINAPI
IoAllocateIrp( CCHAR stack_size
, BOOLEAN charge_quota
)
655 CCHAR loc_count
= stack_size
;
657 TRACE( "%d, %d\n", stack_size
, charge_quota
);
659 if (loc_count
< 8 && loc_count
!= 1)
662 size
= sizeof(IRP
) + loc_count
* sizeof(IO_STACK_LOCATION
);
663 irp
= ExAllocatePool( NonPagedPool
, size
);
666 IoInitializeIrp( irp
, size
, stack_size
);
667 if (stack_size
>= 1 && stack_size
<= 8)
668 irp
->AllocationFlags
= IRP_ALLOCATED_FIXED_SIZE
;
670 irp
->AllocationFlags
|= IRP_LOOKASIDE_ALLOCATION
;
675 /***********************************************************************
676 * IoFreeIrp (NTOSKRNL.EXE.@)
678 void WINAPI
IoFreeIrp( IRP
*irp
)
682 TRACE( "%p\n", irp
);
684 mdl
= irp
->MdlAddress
;
687 MDL
*next
= mdl
->Next
;
696 /***********************************************************************
697 * IoAllocateErrorLogEntry (NTOSKRNL.EXE.@)
699 PVOID WINAPI
IoAllocateErrorLogEntry( PVOID IoObject
, UCHAR EntrySize
)
701 FIXME( "stub: %p, %u\n", IoObject
, EntrySize
);
706 /***********************************************************************
707 * IoAllocateMdl (NTOSKRNL.EXE.@)
709 PMDL WINAPI
IoAllocateMdl( PVOID va
, ULONG length
, BOOLEAN secondary
, BOOLEAN charge_quota
, IRP
*irp
)
712 ULONG_PTR address
= (ULONG_PTR
)va
;
713 ULONG_PTR page_address
;
714 SIZE_T nb_pages
, mdl_size
;
716 TRACE("(%p, %u, %i, %i, %p)\n", va
, length
, secondary
, charge_quota
, irp
);
719 FIXME("Charge quota is not yet supported\n");
721 /* FIXME: We suppose that page size is 4096 */
722 page_address
= address
& ~(4096 - 1);
723 nb_pages
= (((address
+ length
- 1) & ~(4096 - 1)) - page_address
) / 4096 + 1;
725 mdl_size
= sizeof(MDL
) + nb_pages
* sizeof(PVOID
);
727 mdl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, mdl_size
);
731 mdl
->Size
= mdl_size
;
732 mdl
->Process
= NULL
; /* FIXME: IoGetCurrentProcess */
733 mdl
->StartVa
= (PVOID
)page_address
;
734 mdl
->ByteCount
= length
;
735 mdl
->ByteOffset
= address
- page_address
;
737 if (!irp
) return mdl
;
739 if (secondary
) /* add it at the end */
741 MDL
**pmdl
= &irp
->MdlAddress
;
742 while (*pmdl
) pmdl
= &(*pmdl
)->Next
;
747 mdl
->Next
= irp
->MdlAddress
;
748 irp
->MdlAddress
= mdl
;
754 /***********************************************************************
755 * IoFreeMdl (NTOSKRNL.EXE.@)
757 void WINAPI
IoFreeMdl(PMDL mdl
)
760 HeapFree(GetProcessHeap(), 0, mdl
);
764 /***********************************************************************
765 * IoAllocateWorkItem (NTOSKRNL.EXE.@)
767 PIO_WORKITEM WINAPI
IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject
)
769 FIXME( "stub: %p\n", DeviceObject
);
774 /***********************************************************************
775 * IoAttachDeviceToDeviceStack (NTOSKRNL.EXE.@)
777 PDEVICE_OBJECT WINAPI
IoAttachDeviceToDeviceStack( DEVICE_OBJECT
*source
,
778 DEVICE_OBJECT
*target
)
780 TRACE( "%p, %p\n", source
, target
);
781 target
->AttachedDevice
= source
;
782 source
->StackSize
= target
->StackSize
+ 1;
787 /***********************************************************************
788 * IoBuildDeviceIoControlRequest (NTOSKRNL.EXE.@)
790 PIRP WINAPI
IoBuildDeviceIoControlRequest( ULONG code
, PDEVICE_OBJECT device
,
791 PVOID in_buff
, ULONG in_len
,
792 PVOID out_buff
, ULONG out_len
,
793 BOOLEAN internal
, PKEVENT event
,
794 PIO_STATUS_BLOCK iosb
)
797 PIO_STACK_LOCATION irpsp
;
799 TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
800 code
, device
, in_buff
, in_len
, out_buff
, out_len
, internal
, event
, iosb
);
805 irp
= IoAllocateIrp( device
->StackSize
, FALSE
);
809 irpsp
= IoGetNextIrpStackLocation( irp
);
810 irpsp
->MajorFunction
= internal
? IRP_MJ_INTERNAL_DEVICE_CONTROL
: IRP_MJ_DEVICE_CONTROL
;
811 irpsp
->Parameters
.DeviceIoControl
.IoControlCode
= code
;
812 irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
= in_len
;
813 irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
= out_len
;
814 irpsp
->DeviceObject
= device
;
815 irpsp
->CompletionRoutine
= NULL
;
819 case METHOD_BUFFERED
:
820 irp
->AssociatedIrp
.SystemBuffer
= in_buff
;
822 case METHOD_IN_DIRECT
:
823 case METHOD_OUT_DIRECT
:
824 irp
->AssociatedIrp
.SystemBuffer
= in_buff
;
825 IoAllocateMdl( out_buff
, out_len
, FALSE
, FALSE
, irp
);
828 irpsp
->Parameters
.DeviceIoControl
.Type3InputBuffer
= in_buff
;
832 irp
->RequestorMode
= KernelMode
;
833 irp
->UserBuffer
= out_buff
;
834 irp
->UserIosb
= iosb
;
835 irp
->UserEvent
= event
;
840 /**********************************************************
841 * IoBuildSynchronousFsdRequest (NTOSKRNL.EXE.@)
843 PIRP WINAPI
IoBuildSynchronousFsdRequest(ULONG majorfunc
, PDEVICE_OBJECT device
,
844 PVOID buffer
, ULONG length
, PLARGE_INTEGER startoffset
,
845 PKEVENT event
, PIO_STATUS_BLOCK iosb
)
848 PIO_STACK_LOCATION irpsp
;
850 TRACE("(%d %p %p %d %p %p %p)\n", majorfunc
, device
, buffer
, length
, startoffset
, event
, iosb
);
852 if (!(irp
= IoAllocateIrp( device
->StackSize
, FALSE
))) return NULL
;
854 irpsp
= IoGetNextIrpStackLocation( irp
);
855 irpsp
->MajorFunction
= majorfunc
;
856 irpsp
->DeviceObject
= device
;
857 irpsp
->CompletionRoutine
= NULL
;
859 irp
->AssociatedIrp
.SystemBuffer
= buffer
;
860 if (device
->Flags
& DO_DIRECT_IO
) IoAllocateMdl( buffer
, length
, FALSE
, FALSE
, irp
);
865 irpsp
->Parameters
.Read
.Length
= length
;
866 irpsp
->Parameters
.Read
.ByteOffset
= *startoffset
;
869 irpsp
->Parameters
.Write
.Length
= length
;
870 irpsp
->Parameters
.Write
.ByteOffset
= *startoffset
;
873 irp
->RequestorMode
= KernelMode
;
874 irp
->UserIosb
= iosb
;
875 irp
->UserEvent
= event
;
876 irp
->UserBuffer
= buffer
;
880 static void build_driver_keypath( const WCHAR
*name
, UNICODE_STRING
*keypath
)
882 static const WCHAR driverW
[] = {'\\','D','r','i','v','e','r','\\',0};
885 /* Check what prefix is present */
886 if (strncmpW( name
, servicesW
, strlenW(servicesW
) ) == 0)
888 FIXME( "Driver name %s is malformed as the keypath\n", debugstr_w(name
) );
889 RtlCreateUnicodeString( keypath
, name
);
892 if (strncmpW( name
, driverW
, strlenW(driverW
) ) == 0)
893 name
+= strlenW(driverW
);
895 FIXME( "Driver name %s does not properly begin with \\Driver\\\n", debugstr_w(name
) );
897 str
= HeapAlloc( GetProcessHeap(), 0, sizeof(servicesW
) + strlenW(name
)*sizeof(WCHAR
));
898 lstrcpyW( str
, servicesW
);
899 lstrcatW( str
, name
);
900 RtlInitUnicodeString( keypath
, str
);
904 /***********************************************************************
905 * IoCreateDriver (NTOSKRNL.EXE.@)
907 NTSTATUS WINAPI
IoCreateDriver( UNICODE_STRING
*name
, PDRIVER_INITIALIZE init
)
909 struct wine_driver
*driver
;
912 TRACE("(%s, %p)\n", debugstr_us(name
), init
);
914 if (!(driver
= RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY
,
916 return STATUS_NO_MEMORY
;
918 if ((status
= RtlDuplicateUnicodeString( 1, name
, &driver
->driver_obj
.DriverName
)))
920 RtlFreeHeap( GetProcessHeap(), 0, driver
);
924 driver
->driver_obj
.Size
= sizeof(driver
->driver_obj
);
925 driver
->driver_obj
.DriverInit
= init
;
926 driver
->driver_obj
.DriverExtension
= &driver
->driver_extension
;
927 driver
->driver_extension
.DriverObject
= &driver
->driver_obj
;
928 build_driver_keypath( driver
->driver_obj
.DriverName
.Buffer
, &driver
->driver_extension
.ServiceKeyName
);
930 status
= driver
->driver_obj
.DriverInit( &driver
->driver_obj
, &driver
->driver_extension
.ServiceKeyName
);
934 RtlFreeUnicodeString( &driver
->driver_obj
.DriverName
);
935 RtlFreeUnicodeString( &driver
->driver_extension
.ServiceKeyName
);
936 RtlFreeHeap( GetProcessHeap(), 0, driver
);
940 EnterCriticalSection( &drivers_cs
);
941 if (wine_rb_put( &wine_drivers
, &driver
->driver_obj
.DriverName
, &driver
->entry
))
942 ERR( "failed to insert driver %s in tree\n", debugstr_us(name
) );
943 LeaveCriticalSection( &drivers_cs
);
950 /***********************************************************************
951 * IoDeleteDriver (NTOSKRNL.EXE.@)
953 void WINAPI
IoDeleteDriver( DRIVER_OBJECT
*driver_object
)
955 TRACE( "(%p)\n", driver_object
);
957 EnterCriticalSection( &drivers_cs
);
958 wine_rb_remove( &wine_drivers
, &driver_object
->DriverName
);
959 LeaveCriticalSection( &drivers_cs
);
961 RtlFreeUnicodeString( &driver_object
->DriverName
);
962 RtlFreeUnicodeString( &driver_object
->DriverExtension
->ServiceKeyName
);
963 RtlFreeHeap( GetProcessHeap(), 0, CONTAINING_RECORD( driver_object
, struct wine_driver
, driver_obj
) );
967 /***********************************************************************
968 * IoCreateDevice (NTOSKRNL.EXE.@)
970 NTSTATUS WINAPI
IoCreateDevice( DRIVER_OBJECT
*driver
, ULONG ext_size
,
971 UNICODE_STRING
*name
, DEVICE_TYPE type
,
972 ULONG characteristics
, BOOLEAN exclusive
,
973 DEVICE_OBJECT
**ret_device
)
976 DEVICE_OBJECT
*device
;
978 HANDLE manager
= get_device_manager();
980 TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n",
981 driver
, ext_size
, debugstr_us(name
), type
, characteristics
, exclusive
, ret_device
);
983 if (!(device
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*device
) + ext_size
)))
984 return STATUS_NO_MEMORY
;
986 SERVER_START_REQ( create_device
)
991 req
->manager
= wine_server_obj_handle( manager
);
992 req
->user_ptr
= wine_server_client_ptr( device
);
993 if (name
) wine_server_add_data( req
, name
->Buffer
, name
->Length
);
994 if (!(status
= wine_server_call( req
))) handle
= wine_server_ptr_handle( reply
->handle
);
998 if (status
== STATUS_SUCCESS
)
1000 device
->DriverObject
= driver
;
1001 device
->DeviceExtension
= device
+ 1;
1002 device
->DeviceType
= type
;
1003 device
->StackSize
= 1;
1004 device
->Reserved
= handle
;
1006 device
->NextDevice
= driver
->DeviceObject
;
1007 driver
->DeviceObject
= device
;
1009 *ret_device
= device
;
1011 else HeapFree( GetProcessHeap(), 0, device
);
1017 /***********************************************************************
1018 * IoDeleteDevice (NTOSKRNL.EXE.@)
1020 void WINAPI
IoDeleteDevice( DEVICE_OBJECT
*device
)
1024 TRACE( "%p\n", device
);
1026 SERVER_START_REQ( delete_device
)
1028 req
->handle
= wine_server_obj_handle( device
->Reserved
);
1029 status
= wine_server_call( req
);
1033 if (status
== STATUS_SUCCESS
)
1035 DEVICE_OBJECT
**prev
= &device
->DriverObject
->DeviceObject
;
1036 while (*prev
&& *prev
!= device
) prev
= &(*prev
)->NextDevice
;
1037 if (*prev
) *prev
= (*prev
)->NextDevice
;
1038 NtClose( device
->Reserved
);
1039 HeapFree( GetProcessHeap(), 0, device
);
1044 /***********************************************************************
1045 * IoCreateSymbolicLink (NTOSKRNL.EXE.@)
1047 NTSTATUS WINAPI
IoCreateSymbolicLink( UNICODE_STRING
*name
, UNICODE_STRING
*target
)
1050 OBJECT_ATTRIBUTES attr
;
1052 attr
.Length
= sizeof(attr
);
1053 attr
.RootDirectory
= 0;
1054 attr
.ObjectName
= name
;
1055 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
;
1056 attr
.SecurityDescriptor
= NULL
;
1057 attr
.SecurityQualityOfService
= NULL
;
1059 TRACE( "%s -> %s\n", debugstr_us(name
), debugstr_us(target
) );
1060 /* FIXME: store handle somewhere */
1061 return NtCreateSymbolicLinkObject( &handle
, SYMBOLIC_LINK_ALL_ACCESS
, &attr
, target
);
1065 /***********************************************************************
1066 * IoDeleteSymbolicLink (NTOSKRNL.EXE.@)
1068 NTSTATUS WINAPI
IoDeleteSymbolicLink( UNICODE_STRING
*name
)
1071 OBJECT_ATTRIBUTES attr
;
1074 attr
.Length
= sizeof(attr
);
1075 attr
.RootDirectory
= 0;
1076 attr
.ObjectName
= name
;
1077 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
1078 attr
.SecurityDescriptor
= NULL
;
1079 attr
.SecurityQualityOfService
= NULL
;
1081 if (!(status
= NtOpenSymbolicLinkObject( &handle
, 0, &attr
)))
1083 SERVER_START_REQ( unlink_object
)
1085 req
->handle
= wine_server_obj_handle( handle
);
1086 status
= wine_server_call( req
);
1095 /***********************************************************************
1096 * IoGetDeviceInterfaces (NTOSKRNL.EXE.@)
1098 NTSTATUS WINAPI
IoGetDeviceInterfaces( const GUID
*InterfaceClassGuid
,
1099 PDEVICE_OBJECT PhysicalDeviceObject
,
1100 ULONG Flags
, PWSTR
*SymbolicLinkList
)
1102 FIXME( "stub: %s %p %x %p\n", debugstr_guid(InterfaceClassGuid
),
1103 PhysicalDeviceObject
, Flags
, SymbolicLinkList
);
1104 return STATUS_NOT_IMPLEMENTED
;
1108 /***********************************************************************
1109 * IoGetDeviceObjectPointer (NTOSKRNL.EXE.@)
1111 NTSTATUS WINAPI
IoGetDeviceObjectPointer( UNICODE_STRING
*name
, ACCESS_MASK access
, PFILE_OBJECT
*file
, PDEVICE_OBJECT
*device
)
1113 static DEVICE_OBJECT stub_device
;
1114 static DRIVER_OBJECT stub_driver
;
1116 FIXME( "stub: %s %x %p %p\n", debugstr_us(name
), access
, file
, device
);
1118 stub_device
.StackSize
= 0x80; /* minimum value to appease SecuROM 5.x */
1119 stub_device
.DriverObject
= &stub_driver
;
1122 *device
= &stub_device
;
1124 return STATUS_SUCCESS
;
1127 /***********************************************************************
1128 * IoGetAttachedDevice (NTOSKRNL.EXE.@)
1130 PDEVICE_OBJECT WINAPI
IoGetAttachedDevice( PDEVICE_OBJECT device
)
1132 FIXME( "stub: %p\n", device
);
1137 /***********************************************************************
1138 * IoGetDeviceProperty (NTOSKRNL.EXE.@)
1140 NTSTATUS WINAPI
IoGetDeviceProperty( DEVICE_OBJECT
*device
, DEVICE_REGISTRY_PROPERTY device_property
,
1141 ULONG buffer_length
, PVOID property_buffer
, PULONG result_length
)
1143 NTSTATUS status
= STATUS_NOT_IMPLEMENTED
;
1144 TRACE( "%p %d %u %p %p\n", device
, device_property
, buffer_length
,
1145 property_buffer
, result_length
);
1146 switch (device_property
)
1148 case DevicePropertyPhysicalDeviceObjectName
:
1150 ULONG used_len
, len
= buffer_length
+ sizeof(OBJECT_NAME_INFORMATION
);
1151 OBJECT_NAME_INFORMATION
*name
= HeapAlloc(GetProcessHeap(), 0, len
);
1153 status
= NtQueryObject(device
->Reserved
, ObjectNameInformation
, name
, len
, &used_len
);
1154 if (status
== STATUS_SUCCESS
)
1156 /* Ensure room for NULL termination */
1157 if (buffer_length
>= name
->Name
.MaximumLength
)
1158 memcpy(property_buffer
, name
->Name
.Buffer
, name
->Name
.MaximumLength
);
1160 status
= STATUS_BUFFER_TOO_SMALL
;
1161 *result_length
= name
->Name
.MaximumLength
;
1165 if (status
== STATUS_INFO_LENGTH_MISMATCH
||
1166 status
== STATUS_BUFFER_OVERFLOW
)
1168 status
= STATUS_BUFFER_TOO_SMALL
;
1169 *result_length
= used_len
- sizeof(OBJECT_NAME_INFORMATION
);
1174 HeapFree(GetProcessHeap(), 0, name
);
1178 FIXME("unhandled property %d\n", device_property
);
1184 /***********************************************************************
1185 * IoCallDriver (NTOSKRNL.EXE.@)
1187 NTSTATUS WINAPI
IoCallDriver( DEVICE_OBJECT
*device
, IRP
*irp
)
1189 PDRIVER_DISPATCH dispatch
;
1190 IO_STACK_LOCATION
*irpsp
;
1193 --irp
->CurrentLocation
;
1194 irpsp
= --irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
;
1195 dispatch
= device
->DriverObject
->MajorFunction
[irpsp
->MajorFunction
];
1197 if (TRACE_ON(relay
))
1198 DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
1199 GetCurrentThreadId(), dispatch
, device
, irp
);
1201 status
= dispatch( device
, irp
);
1203 if (TRACE_ON(relay
))
1204 DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
1205 GetCurrentThreadId(), dispatch
, device
, irp
, status
);
1211 /***********************************************************************
1212 * IofCallDriver (NTOSKRNL.EXE.@)
1214 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1215 DEFINE_FASTCALL2_ENTRYPOINT( IofCallDriver
)
1216 NTSTATUS WINAPI
__regs_IofCallDriver( DEVICE_OBJECT
*device
, IRP
*irp
)
1218 NTSTATUS WINAPI
IofCallDriver( DEVICE_OBJECT
*device
, IRP
*irp
)
1221 TRACE( "%p %p\n", device
, irp
);
1222 return IoCallDriver( device
, irp
);
1226 /***********************************************************************
1227 * IoGetRelatedDeviceObject (NTOSKRNL.EXE.@)
1229 PDEVICE_OBJECT WINAPI
IoGetRelatedDeviceObject( PFILE_OBJECT obj
)
1231 FIXME( "stub: %p\n", obj
);
1235 static CONFIGURATION_INFORMATION configuration_information
;
1237 /***********************************************************************
1238 * IoGetConfigurationInformation (NTOSKRNL.EXE.@)
1240 PCONFIGURATION_INFORMATION WINAPI
IoGetConfigurationInformation(void)
1242 FIXME( "partial stub\n" );
1243 /* FIXME: return actual devices on system */
1244 return &configuration_information
;
1248 /***********************************************************************
1249 * IoIsWdmVersionAvailable (NTOSKRNL.EXE.@)
1251 NTSTATUS WINAPI
IoIsWdmVersionAvailable(UCHAR MajorVersion
, UCHAR MinorVersion
)
1257 TRACE( "%d, 0x%X\n", MajorVersion
, MinorVersion
);
1259 version
= GetVersion();
1260 major
= LOBYTE(version
);
1261 minor
= HIBYTE(LOWORD(version
));
1263 if (MajorVersion
== 6 && MinorVersion
== 0)
1265 /* Windows Vista, Windows Server 2008, Windows 7 */
1267 else if (MajorVersion
== 1)
1269 if (MinorVersion
== 0x30)
1271 /* Windows server 2003 */
1275 else if (MinorVersion
== 0x20)
1281 else if (MinorVersion
== 0x10)
1287 else if (MinorVersion
== 0x05)
1291 MinorVersion
= 0x5a;
1293 else if (MinorVersion
== 0x00)
1297 MinorVersion
= 0x0a;
1301 FIXME( "unknown major %d minor 0x%X\n", MajorVersion
, MinorVersion
);
1307 FIXME( "unknown major %d minor 0x%X\n", MajorVersion
, MinorVersion
);
1310 return major
> MajorVersion
|| (major
== MajorVersion
&& minor
>= MinorVersion
);
1314 /***********************************************************************
1315 * IoQueryDeviceDescription (NTOSKRNL.EXE.@)
1317 NTSTATUS WINAPI
IoQueryDeviceDescription(PINTERFACE_TYPE itype
, PULONG bus
, PCONFIGURATION_TYPE ctype
,
1318 PULONG cnum
, PCONFIGURATION_TYPE ptype
, PULONG pnum
,
1319 PIO_QUERY_DEVICE_ROUTINE callout
, PVOID context
)
1321 FIXME( "(%p %p %p %p %p %p %p %p)\n", itype
, bus
, ctype
, cnum
, ptype
, pnum
, callout
, context
);
1322 return STATUS_NOT_IMPLEMENTED
;
1326 /***********************************************************************
1327 * IoRegisterDriverReinitialization (NTOSKRNL.EXE.@)
1329 void WINAPI
IoRegisterDriverReinitialization( PDRIVER_OBJECT obj
, PDRIVER_REINITIALIZE reinit
, PVOID context
)
1331 FIXME( "stub: %p %p %p\n", obj
, reinit
, context
);
1335 /***********************************************************************
1336 * IoRegisterShutdownNotification (NTOSKRNL.EXE.@)
1338 NTSTATUS WINAPI
IoRegisterShutdownNotification( PDEVICE_OBJECT obj
)
1340 FIXME( "stub: %p\n", obj
);
1341 return STATUS_SUCCESS
;
1345 /***********************************************************************
1346 * IoUnregisterShutdownNotification (NTOSKRNL.EXE.@)
1348 VOID WINAPI
IoUnregisterShutdownNotification( PDEVICE_OBJECT obj
)
1350 FIXME( "stub: %p\n", obj
);
1354 /***********************************************************************
1355 * IoReportResourceUsage (NTOSKRNL.EXE.@)
1357 NTSTATUS WINAPI
IoReportResourceUsage(PUNICODE_STRING name
, PDRIVER_OBJECT drv_obj
, PCM_RESOURCE_LIST drv_list
,
1358 ULONG drv_size
, PDRIVER_OBJECT dev_obj
, PCM_RESOURCE_LIST dev_list
,
1359 ULONG dev_size
, BOOLEAN overwrite
, PBOOLEAN detected
)
1361 FIXME( "(%s, %p, %p, %u, %p, %p, %u, %d, %p): stub\n", debugstr_us(name
),
1362 drv_obj
, drv_list
, drv_size
, dev_obj
, dev_list
, dev_size
, overwrite
, detected
);
1363 return STATUS_NOT_IMPLEMENTED
;
1367 /***********************************************************************
1368 * IoCompleteRequest (NTOSKRNL.EXE.@)
1370 VOID WINAPI
IoCompleteRequest( IRP
*irp
, UCHAR priority_boost
)
1372 IO_STACK_LOCATION
*irpsp
;
1373 PIO_COMPLETION_ROUTINE routine
;
1374 NTSTATUS status
, stat
;
1378 TRACE( "%p %u\n", irp
, priority_boost
);
1380 status
= irp
->IoStatus
.u
.Status
;
1381 while (irp
->CurrentLocation
<= irp
->StackCount
)
1383 irpsp
= irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
;
1384 routine
= irpsp
->CompletionRoutine
;
1386 /* FIXME: add SL_INVOKE_ON_CANCEL support */
1389 if ((irpsp
->Control
& SL_INVOKE_ON_SUCCESS
) && STATUS_SUCCESS
== status
)
1391 if ((irpsp
->Control
& SL_INVOKE_ON_ERROR
) && STATUS_SUCCESS
!= status
)
1394 ++irp
->CurrentLocation
;
1395 ++irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
;
1398 TRACE( "calling %p( %p, %p, %p )\n", routine
,
1399 irpsp
->DeviceObject
, irp
, irpsp
->Context
);
1400 stat
= routine( irpsp
->DeviceObject
, irp
, irpsp
->Context
);
1401 TRACE( "CompletionRoutine returned %x\n", stat
);
1402 if (STATUS_MORE_PROCESSING_REQUIRED
== stat
)
1407 handle
= (HANDLE
)irp
->UserIosb
;
1410 void *out_buff
= irp
->UserBuffer
;
1411 FILE_OBJECT
*file
= irp
->Tail
.Overlay
.OriginalFileObject
;
1413 SERVER_START_REQ( set_irp_result
)
1415 req
->handle
= wine_server_obj_handle( handle
);
1416 req
->status
= irp
->IoStatus
.u
.Status
;
1417 req
->file_ptr
= wine_server_client_ptr( file
);
1418 if (irp
->IoStatus
.u
.Status
>= 0)
1420 req
->size
= irp
->IoStatus
.Information
;
1421 if (out_buff
) wine_server_add_data( req
, out_buff
, irp
->IoStatus
.Information
);
1423 wine_server_call( req
);
1426 HeapFree( GetProcessHeap(), 0, out_buff
);
1433 /***********************************************************************
1434 * IofCompleteRequest (NTOSKRNL.EXE.@)
1436 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1437 DEFINE_FASTCALL2_ENTRYPOINT( IofCompleteRequest
)
1438 void WINAPI
__regs_IofCompleteRequest( IRP
*irp
, UCHAR priority_boost
)
1440 void WINAPI
IofCompleteRequest( IRP
*irp
, UCHAR priority_boost
)
1443 TRACE( "%p %u\n", irp
, priority_boost
);
1444 IoCompleteRequest( irp
, priority_boost
);
1448 /***********************************************************************
1449 * InterlockedCompareExchange (NTOSKRNL.EXE.@)
1451 #ifdef DEFINE_FASTCALL3_ENTRYPOINT
1452 DEFINE_FASTCALL3_ENTRYPOINT( NTOSKRNL_InterlockedCompareExchange
)
1453 LONG WINAPI
__regs_NTOSKRNL_InterlockedCompareExchange( LONG
volatile *dest
, LONG xchg
, LONG compare
)
1455 LONG WINAPI
NTOSKRNL_InterlockedCompareExchange( LONG
volatile *dest
, LONG xchg
, LONG compare
)
1458 return InterlockedCompareExchange( dest
, xchg
, compare
);
1462 /***********************************************************************
1463 * InterlockedDecrement (NTOSKRNL.EXE.@)
1465 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1466 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedDecrement
)
1467 LONG WINAPI
__regs_NTOSKRNL_InterlockedDecrement( LONG
volatile *dest
)
1469 LONG WINAPI
NTOSKRNL_InterlockedDecrement( LONG
volatile *dest
)
1472 return InterlockedDecrement( dest
);
1476 /***********************************************************************
1477 * InterlockedExchange (NTOSKRNL.EXE.@)
1479 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1480 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchange
)
1481 LONG WINAPI
__regs_NTOSKRNL_InterlockedExchange( LONG
volatile *dest
, LONG val
)
1483 LONG WINAPI
NTOSKRNL_InterlockedExchange( LONG
volatile *dest
, LONG val
)
1486 return InterlockedExchange( dest
, val
);
1490 /***********************************************************************
1491 * InterlockedExchangeAdd (NTOSKRNL.EXE.@)
1493 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1494 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchangeAdd
)
1495 LONG WINAPI
__regs_NTOSKRNL_InterlockedExchangeAdd( LONG
volatile *dest
, LONG incr
)
1497 LONG WINAPI
NTOSKRNL_InterlockedExchangeAdd( LONG
volatile *dest
, LONG incr
)
1500 return InterlockedExchangeAdd( dest
, incr
);
1504 /***********************************************************************
1505 * InterlockedIncrement (NTOSKRNL.EXE.@)
1507 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1508 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedIncrement
)
1509 LONG WINAPI
__regs_NTOSKRNL_InterlockedIncrement( LONG
volatile *dest
)
1511 LONG WINAPI
NTOSKRNL_InterlockedIncrement( LONG
volatile *dest
)
1514 return InterlockedIncrement( dest
);
1518 /***********************************************************************
1519 * InterlockedPopEntrySList (NTOSKRNL.EXE.@)
1521 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1522 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedPopEntrySList
)
1523 PSLIST_ENTRY WINAPI
__regs_NTOSKRNL_InterlockedPopEntrySList( PSLIST_HEADER list
)
1525 PSLIST_ENTRY WINAPI
NTOSKRNL_InterlockedPopEntrySList( PSLIST_HEADER list
)
1528 return InterlockedPopEntrySList( list
);
1532 /***********************************************************************
1533 * InterlockedPushEntrySList (NTOSKRNL.EXE.@)
1535 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1536 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedPushEntrySList
)
1537 PSLIST_ENTRY WINAPI
__regs_NTOSKRNL_InterlockedPushEntrySList( PSLIST_HEADER list
, PSLIST_ENTRY entry
)
1539 PSLIST_ENTRY WINAPI
NTOSKRNL_InterlockedPushEntrySList( PSLIST_HEADER list
, PSLIST_ENTRY entry
)
1542 return InterlockedPushEntrySList( list
, entry
);
1546 /***********************************************************************
1547 * ExAllocatePool (NTOSKRNL.EXE.@)
1549 PVOID WINAPI
ExAllocatePool( POOL_TYPE type
, SIZE_T size
)
1551 return ExAllocatePoolWithTag( type
, size
, 0 );
1555 /***********************************************************************
1556 * ExAllocatePoolWithQuota (NTOSKRNL.EXE.@)
1558 PVOID WINAPI
ExAllocatePoolWithQuota( POOL_TYPE type
, SIZE_T size
)
1560 return ExAllocatePoolWithTag( type
, size
, 0 );
1564 /***********************************************************************
1565 * ExAllocatePoolWithTag (NTOSKRNL.EXE.@)
1567 PVOID WINAPI
ExAllocatePoolWithTag( POOL_TYPE type
, SIZE_T size
, ULONG tag
)
1569 /* FIXME: handle page alignment constraints */
1570 void *ret
= HeapAlloc( GetProcessHeap(), 0, size
);
1571 TRACE( "%lu pool %u -> %p\n", size
, type
, ret
);
1576 /***********************************************************************
1577 * ExAllocatePoolWithQuotaTag (NTOSKRNL.EXE.@)
1579 PVOID WINAPI
ExAllocatePoolWithQuotaTag( POOL_TYPE type
, SIZE_T size
, ULONG tag
)
1581 return ExAllocatePoolWithTag( type
, size
, tag
);
1585 /***********************************************************************
1586 * ExCreateCallback (NTOSKRNL.EXE.@)
1588 NTSTATUS WINAPI
ExCreateCallback(PCALLBACK_OBJECT
*obj
, POBJECT_ATTRIBUTES attr
,
1589 BOOLEAN create
, BOOLEAN allow_multiple
)
1591 FIXME("(%p, %p, %u, %u): stub\n", obj
, attr
, create
, allow_multiple
);
1593 return STATUS_NOT_IMPLEMENTED
;
1597 /***********************************************************************
1598 * ExDeleteNPagedLookasideList (NTOSKRNL.EXE.@)
1600 void WINAPI
ExDeleteNPagedLookasideList( PNPAGED_LOOKASIDE_LIST lookaside
)
1602 FIXME("(%p) stub\n", lookaside
);
1606 /***********************************************************************
1607 * ExDeletePagedLookasideList (NTOSKRNL.EXE.@)
1609 void WINAPI
ExDeletePagedLookasideList( PPAGED_LOOKASIDE_LIST lookaside
)
1611 FIXME("(%p) stub\n", lookaside
);
1615 /***********************************************************************
1616 * ExFreePool (NTOSKRNL.EXE.@)
1618 void WINAPI
ExFreePool( void *ptr
)
1620 ExFreePoolWithTag( ptr
, 0 );
1624 /***********************************************************************
1625 * ExFreePoolWithTag (NTOSKRNL.EXE.@)
1627 void WINAPI
ExFreePoolWithTag( void *ptr
, ULONG tag
)
1629 TRACE( "%p\n", ptr
);
1630 HeapFree( GetProcessHeap(), 0, ptr
);
1634 /***********************************************************************
1635 * ExInitializeResourceLite (NTOSKRNL.EXE.@)
1637 NTSTATUS WINAPI
ExInitializeResourceLite(PERESOURCE Resource
)
1639 FIXME( "stub: %p\n", Resource
);
1640 return STATUS_NOT_IMPLEMENTED
;
1644 /***********************************************************************
1645 * ExInitializeNPagedLookasideList (NTOSKRNL.EXE.@)
1647 void WINAPI
ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside
,
1648 PALLOCATE_FUNCTION Allocate
,
1649 PFREE_FUNCTION Free
,
1655 FIXME( "stub: %p, %p, %p, %u, %lu, %u, %u\n", Lookaside
, Allocate
, Free
, Flags
, Size
, Tag
, Depth
);
1658 /***********************************************************************
1659 * ExInitializePagedLookasideList (NTOSKRNL.EXE.@)
1661 void WINAPI
ExInitializePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside
,
1662 PALLOCATE_FUNCTION Allocate
,
1663 PFREE_FUNCTION Free
,
1669 FIXME( "stub: %p, %p, %p, %u, %lu, %u, %u\n", Lookaside
, Allocate
, Free
, Flags
, Size
, Tag
, Depth
);
1672 /***********************************************************************
1673 * ExInitializeZone (NTOSKRNL.EXE.@)
1675 NTSTATUS WINAPI
ExInitializeZone(PZONE_HEADER Zone
,
1677 PVOID InitialSegment
,
1678 ULONG InitialSegmentSize
)
1680 FIXME( "stub: %p, %u, %p, %u\n", Zone
, BlockSize
, InitialSegment
, InitialSegmentSize
);
1681 return STATUS_NOT_IMPLEMENTED
;
1684 /***********************************************************************
1685 * FsRtlRegisterUncProvider (NTOSKRNL.EXE.@)
1687 NTSTATUS WINAPI
FsRtlRegisterUncProvider(PHANDLE MupHandle
, PUNICODE_STRING RedirDevName
,
1688 BOOLEAN MailslotsSupported
)
1690 FIXME("(%p %p %d): stub\n", MupHandle
, RedirDevName
, MailslotsSupported
);
1691 return STATUS_NOT_IMPLEMENTED
;
1694 /***********************************************************************
1695 * IoGetCurrentProcess / PsGetCurrentProcess (NTOSKRNL.EXE.@)
1697 PEPROCESS WINAPI
IoGetCurrentProcess(void)
1703 /***********************************************************************
1704 * KeGetCurrentThread / PsGetCurrentThread (NTOSKRNL.EXE.@)
1706 PRKTHREAD WINAPI
KeGetCurrentThread(void)
1712 /***********************************************************************
1713 * KeInitializeEvent (NTOSKRNL.EXE.@)
1715 void WINAPI
KeInitializeEvent( PRKEVENT Event
, EVENT_TYPE Type
, BOOLEAN State
)
1717 FIXME( "stub: %p %d %d\n", Event
, Type
, State
);
1721 /***********************************************************************
1722 * KeInitializeMutex (NTOSKRNL.EXE.@)
1724 void WINAPI
KeInitializeMutex(PRKMUTEX Mutex
, ULONG Level
)
1726 FIXME( "stub: %p, %u\n", Mutex
, Level
);
1730 /***********************************************************************
1731 * KeWaitForMutexObject (NTOSKRNL.EXE.@)
1733 NTSTATUS WINAPI
KeWaitForMutexObject(PRKMUTEX Mutex
, KWAIT_REASON WaitReason
, KPROCESSOR_MODE WaitMode
,
1734 BOOLEAN Alertable
, PLARGE_INTEGER Timeout
)
1736 FIXME( "stub: %p, %d, %d, %d, %p\n", Mutex
, WaitReason
, WaitMode
, Alertable
, Timeout
);
1737 return STATUS_NOT_IMPLEMENTED
;
1741 /***********************************************************************
1742 * KeReleaseMutex (NTOSKRNL.EXE.@)
1744 LONG WINAPI
KeReleaseMutex(PRKMUTEX Mutex
, BOOLEAN Wait
)
1746 FIXME( "stub: %p, %d\n", Mutex
, Wait
);
1747 return STATUS_NOT_IMPLEMENTED
;
1751 /***********************************************************************
1752 * KeInitializeSemaphore (NTOSKRNL.EXE.@)
1754 void WINAPI
KeInitializeSemaphore( PRKSEMAPHORE Semaphore
, LONG Count
, LONG Limit
)
1756 FIXME( "(%p %d %d) stub\n", Semaphore
, Count
, Limit
);
1760 /***********************************************************************
1761 * KeInitializeSpinLock (NTOSKRNL.EXE.@)
1763 void WINAPI
KeInitializeSpinLock( PKSPIN_LOCK SpinLock
)
1765 FIXME( "stub: %p\n", SpinLock
);
1769 /***********************************************************************
1770 * KeInitializeTimerEx (NTOSKRNL.EXE.@)
1772 void WINAPI
KeInitializeTimerEx( PKTIMER Timer
, TIMER_TYPE Type
)
1774 FIXME( "stub: %p %d\n", Timer
, Type
);
1778 /***********************************************************************
1779 * KeInitializeTimer (NTOSKRNL.EXE.@)
1781 void WINAPI
KeInitializeTimer( PKTIMER Timer
)
1783 KeInitializeTimerEx(Timer
, NotificationTimer
);
1786 /***********************************************************************
1787 * KeInsertQueue (NTOSKRNL.EXE.@)
1789 LONG WINAPI
KeInsertQueue(PRKQUEUE Queue
, PLIST_ENTRY Entry
)
1791 FIXME( "stub: %p %p\n", Queue
, Entry
);
1795 /**********************************************************************
1796 * KeQueryActiveProcessors (NTOSKRNL.EXE.@)
1798 * Return the active Processors as bitmask
1801 * active Processors as bitmask
1804 KAFFINITY WINAPI
KeQueryActiveProcessors( void )
1806 DWORD_PTR AffinityMask
;
1808 GetProcessAffinityMask( GetCurrentProcess(), &AffinityMask
, NULL
);
1809 return AffinityMask
;
1813 /**********************************************************************
1814 * KeQueryInterruptTime (NTOSKRNL.EXE.@)
1816 * Return the interrupt time count
1819 ULONGLONG WINAPI
KeQueryInterruptTime( void )
1821 LARGE_INTEGER totaltime
;
1823 KeQueryTickCount(&totaltime
);
1824 return totaltime
.QuadPart
;
1828 /***********************************************************************
1829 * KeQuerySystemTime (NTOSKRNL.EXE.@)
1831 void WINAPI
KeQuerySystemTime( LARGE_INTEGER
*time
)
1833 NtQuerySystemTime( time
);
1837 /***********************************************************************
1838 * KeQueryTickCount (NTOSKRNL.EXE.@)
1840 void WINAPI
KeQueryTickCount( LARGE_INTEGER
*count
)
1842 count
->QuadPart
= NtGetTickCount();
1843 /* update the global variable too */
1844 KeTickCount
.LowPart
= count
->u
.LowPart
;
1845 KeTickCount
.High1Time
= count
->u
.HighPart
;
1846 KeTickCount
.High2Time
= count
->u
.HighPart
;
1850 /***********************************************************************
1851 * KeReleaseSemaphore (NTOSKRNL.EXE.@)
1853 LONG WINAPI
KeReleaseSemaphore( PRKSEMAPHORE Semaphore
, KPRIORITY Increment
,
1854 LONG Adjustment
, BOOLEAN Wait
)
1856 FIXME("(%p %d %d %d) stub\n", Semaphore
, Increment
, Adjustment
, Wait
);
1861 /***********************************************************************
1862 * KeQueryTimeIncrement (NTOSKRNL.EXE.@)
1864 ULONG WINAPI
KeQueryTimeIncrement(void)
1870 /***********************************************************************
1871 * KeResetEvent (NTOSKRNL.EXE.@)
1873 LONG WINAPI
KeResetEvent( PRKEVENT Event
)
1875 FIXME("(%p): stub\n", Event
);
1880 /***********************************************************************
1881 * KeSetEvent (NTOSKRNL.EXE.@)
1883 LONG WINAPI
KeSetEvent( PRKEVENT Event
, KPRIORITY Increment
, BOOLEAN Wait
)
1885 FIXME("(%p, %d, %d): stub\n", Event
, Increment
, Wait
);
1890 /***********************************************************************
1891 * KeSetPriorityThread (NTOSKRNL.EXE.@)
1893 KPRIORITY WINAPI
KeSetPriorityThread( PKTHREAD Thread
, KPRIORITY Priority
)
1895 FIXME("(%p %d)\n", Thread
, Priority
);
1899 /***********************************************************************
1900 * KeSetSystemAffinityThread (NTOSKRNL.EXE.@)
1902 VOID WINAPI
KeSetSystemAffinityThread(KAFFINITY Affinity
)
1904 FIXME("(%lx) stub\n", Affinity
);
1907 /***********************************************************************
1908 * KeWaitForSingleObject (NTOSKRNL.EXE.@)
1910 NTSTATUS WINAPI
KeWaitForSingleObject(PVOID Object
,
1911 KWAIT_REASON WaitReason
,
1912 KPROCESSOR_MODE WaitMode
,
1914 PLARGE_INTEGER Timeout
)
1916 FIXME( "stub: %p, %d, %d, %d, %p\n", Object
, WaitReason
, WaitMode
, Alertable
, Timeout
);
1917 return STATUS_NOT_IMPLEMENTED
;
1920 /***********************************************************************
1921 * IoRegisterFileSystem (NTOSKRNL.EXE.@)
1923 VOID WINAPI
IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject
)
1925 FIXME("(%p): stub\n", DeviceObject
);
1928 /***********************************************************************
1929 * IoUnregisterFileSystem (NTOSKRNL.EXE.@)
1931 VOID WINAPI
IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject
)
1933 FIXME("(%p): stub\n", DeviceObject
);
1936 /***********************************************************************
1937 * MmAllocateNonCachedMemory (NTOSKRNL.EXE.@)
1939 PVOID WINAPI
MmAllocateNonCachedMemory( SIZE_T size
)
1941 TRACE( "%lu\n", size
);
1942 return VirtualAlloc( NULL
, size
, MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
|PAGE_NOCACHE
);
1945 /***********************************************************************
1946 * MmAllocateContiguousMemory (NTOSKRNL.EXE.@)
1948 PVOID WINAPI
MmAllocateContiguousMemory( SIZE_T size
, PHYSICAL_ADDRESS highest_valid_address
)
1950 FIXME( "%lu, %s stub\n", size
, wine_dbgstr_longlong(highest_valid_address
.QuadPart
) );
1954 /***********************************************************************
1955 * MmAllocateContiguousMemorySpecifyCache (NTOSKRNL.EXE.@)
1957 PVOID WINAPI
MmAllocateContiguousMemorySpecifyCache( SIZE_T size
,
1958 PHYSICAL_ADDRESS lowest_valid_address
,
1959 PHYSICAL_ADDRESS highest_valid_address
,
1960 PHYSICAL_ADDRESS BoundaryAddressMultiple
,
1961 MEMORY_CACHING_TYPE CacheType
)
1967 /***********************************************************************
1968 * MmAllocatePagesForMdl (NTOSKRNL.EXE.@)
1970 PMDL WINAPI
MmAllocatePagesForMdl(PHYSICAL_ADDRESS lowaddress
, PHYSICAL_ADDRESS highaddress
,
1971 PHYSICAL_ADDRESS skipbytes
, SIZE_T size
)
1973 FIXME("%s %s %s %lu: stub\n", wine_dbgstr_longlong(lowaddress
.QuadPart
), wine_dbgstr_longlong(highaddress
.QuadPart
),
1974 wine_dbgstr_longlong(skipbytes
.QuadPart
), size
);
1978 /***********************************************************************
1979 * MmFreeNonCachedMemory (NTOSKRNL.EXE.@)
1981 void WINAPI
MmFreeNonCachedMemory( void *addr
, SIZE_T size
)
1983 TRACE( "%p %lu\n", addr
, size
);
1984 VirtualFree( addr
, 0, MEM_RELEASE
);
1987 /***********************************************************************
1988 * MmIsAddressValid (NTOSKRNL.EXE.@)
1990 * Check if the process can access the virtual address without a pagefault
1993 * VirtualAddress [I] Address to check
1997 * Success: TRUE (Accessing the Address works without a Pagefault)
2000 BOOLEAN WINAPI
MmIsAddressValid(PVOID VirtualAddress
)
2002 TRACE("(%p)\n", VirtualAddress
);
2003 return !IsBadWritePtr(VirtualAddress
, 1);
2006 /***********************************************************************
2007 * MmMapIoSpace (NTOSKRNL.EXE.@)
2009 PVOID WINAPI
MmMapIoSpace( PHYSICAL_ADDRESS PhysicalAddress
, DWORD NumberOfBytes
, DWORD CacheType
)
2011 FIXME( "stub: 0x%08x%08x, %d, %d\n", PhysicalAddress
.u
.HighPart
, PhysicalAddress
.u
.LowPart
, NumberOfBytes
, CacheType
);
2016 /***********************************************************************
2017 * MmLockPagableSectionByHandle (NTOSKRNL.EXE.@)
2019 VOID WINAPI
MmLockPagableSectionByHandle(PVOID ImageSectionHandle
)
2021 FIXME("stub %p\n", ImageSectionHandle
);
2024 /***********************************************************************
2025 * MmMapLockedPagesSpecifyCache (NTOSKRNL.EXE.@)
2027 PVOID WINAPI
MmMapLockedPagesSpecifyCache(PMDLX MemoryDescriptorList
, KPROCESSOR_MODE AccessMode
, MEMORY_CACHING_TYPE CacheType
,
2028 PVOID BaseAddress
, ULONG BugCheckOnFailure
, MM_PAGE_PRIORITY Priority
)
2030 FIXME("(%p, %u, %u, %p, %u, %u): stub\n", MemoryDescriptorList
, AccessMode
, CacheType
, BaseAddress
, BugCheckOnFailure
, Priority
);
2035 /***********************************************************************
2036 * MmUnlockPagableImageSection (NTOSKRNL.EXE.@)
2038 VOID WINAPI
MmUnlockPagableImageSection(PVOID ImageSectionHandle
)
2040 FIXME("stub %p\n", ImageSectionHandle
);
2043 /***********************************************************************
2044 * MmPageEntireDriver (NTOSKRNL.EXE.@)
2046 PVOID WINAPI
MmPageEntireDriver(PVOID AddrInSection
)
2048 TRACE("%p\n", AddrInSection
);
2049 return AddrInSection
;
2053 /***********************************************************************
2054 * MmProbeAndLockPages (NTOSKRNL.EXE.@)
2056 void WINAPI
MmProbeAndLockPages(PMDLX MemoryDescriptorList
, KPROCESSOR_MODE AccessMode
, LOCK_OPERATION Operation
)
2058 FIXME("(%p, %u, %u): stub\n", MemoryDescriptorList
, AccessMode
, Operation
);
2062 /***********************************************************************
2063 * MmResetDriverPaging (NTOSKRNL.EXE.@)
2065 void WINAPI
MmResetDriverPaging(PVOID AddrInSection
)
2067 TRACE("%p\n", AddrInSection
);
2071 /***********************************************************************
2072 * MmUnlockPages (NTOSKRNL.EXE.@)
2074 void WINAPI
MmUnlockPages(PMDLX MemoryDescriptorList
)
2076 FIXME("(%p): stub\n", MemoryDescriptorList
);
2080 /***********************************************************************
2081 * MmUnmapIoSpace (NTOSKRNL.EXE.@)
2083 VOID WINAPI
MmUnmapIoSpace( PVOID BaseAddress
, SIZE_T NumberOfBytes
)
2085 FIXME( "stub: %p, %lu\n", BaseAddress
, NumberOfBytes
);
2089 /***********************************************************************
2090 * ObReferenceObjectByHandle (NTOSKRNL.EXE.@)
2092 NTSTATUS WINAPI
ObReferenceObjectByHandle( HANDLE obj
, ACCESS_MASK access
,
2094 KPROCESSOR_MODE mode
, PVOID
* ptr
,
2095 POBJECT_HANDLE_INFORMATION info
)
2097 FIXME( "stub: %p %x %p %d %p %p\n", obj
, access
, type
, mode
, ptr
, info
);
2098 return STATUS_NOT_IMPLEMENTED
;
2101 /***********************************************************************
2102 * ObReferenceObjectByName (NTOSKRNL.EXE.@)
2104 NTSTATUS WINAPI
ObReferenceObjectByName( UNICODE_STRING
*ObjectName
,
2106 ACCESS_STATE
*AccessState
,
2107 ACCESS_MASK DesiredAccess
,
2108 POBJECT_TYPE ObjectType
,
2109 KPROCESSOR_MODE AccessMode
,
2113 struct wine_driver
*driver
;
2114 struct wine_rb_entry
*entry
;
2116 TRACE("mostly-stub:%s %i %p %i %p %i %p %p\n", debugstr_us(ObjectName
),
2117 Attributes
, AccessState
, DesiredAccess
, ObjectType
, AccessMode
,
2118 ParseContext
, Object
);
2120 if (AccessState
) FIXME("Unhandled AccessState\n");
2121 if (DesiredAccess
) FIXME("Unhandled DesiredAccess\n");
2122 if (ParseContext
) FIXME("Unhandled ParseContext\n");
2123 if (ObjectType
) FIXME("Unhandled ObjectType\n");
2125 if (AccessMode
!= KernelMode
)
2127 FIXME("UserMode access not implemented\n");
2128 return STATUS_NOT_IMPLEMENTED
;
2131 EnterCriticalSection(&drivers_cs
);
2132 entry
= wine_rb_get(&wine_drivers
, ObjectName
);
2133 LeaveCriticalSection(&drivers_cs
);
2136 FIXME("Object (%s) not found, may not be tracked.\n", debugstr_us(ObjectName
));
2137 return STATUS_NOT_IMPLEMENTED
;
2140 driver
= WINE_RB_ENTRY_VALUE(entry
, struct wine_driver
, entry
);
2141 *Object
= &driver
->driver_obj
;
2142 return STATUS_SUCCESS
;
2146 /***********************************************************************
2147 * ObDereferenceObject (NTOSKRNL.EXE.@)
2149 void WINAPI
ObDereferenceObject( void *obj
)
2151 TRACE( "(%p): stub\n", obj
);
2155 /***********************************************************************
2156 * ObfReferenceObject (NTOSKRNL.EXE.@)
2158 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
2159 DEFINE_FASTCALL1_ENTRYPOINT( ObfReferenceObject
)
2160 void WINAPI
__regs_ObfReferenceObject( void *obj
)
2162 void WINAPI
ObfReferenceObject( void *obj
)
2165 FIXME( "(%p): stub\n", obj
);
2169 /***********************************************************************
2170 * ObfDereferenceObject (NTOSKRNL.EXE.@)
2172 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
2173 DEFINE_FASTCALL1_ENTRYPOINT( ObfDereferenceObject
)
2174 void WINAPI
__regs_ObfDereferenceObject( void *obj
)
2176 void WINAPI
ObfDereferenceObject( void *obj
)
2179 ObDereferenceObject( obj
);
2183 /***********************************************************************
2184 * PsCreateSystemThread (NTOSKRNL.EXE.@)
2186 NTSTATUS WINAPI
PsCreateSystemThread(PHANDLE ThreadHandle
, ULONG DesiredAccess
,
2187 POBJECT_ATTRIBUTES ObjectAttributes
,
2188 HANDLE ProcessHandle
, PCLIENT_ID ClientId
,
2189 PKSTART_ROUTINE StartRoutine
, PVOID StartContext
)
2191 if (!ProcessHandle
) ProcessHandle
= GetCurrentProcess();
2192 return RtlCreateUserThread(ProcessHandle
, 0, FALSE
, 0, 0,
2193 0, StartRoutine
, StartContext
,
2194 ThreadHandle
, ClientId
);
2197 /***********************************************************************
2198 * PsGetCurrentProcessId (NTOSKRNL.EXE.@)
2200 HANDLE WINAPI
PsGetCurrentProcessId(void)
2202 if (GetCurrentThreadId() == request_thread
)
2203 return UlongToHandle(client_pid
);
2204 return UlongToHandle(GetCurrentProcessId());
2208 /***********************************************************************
2209 * PsGetCurrentThreadId (NTOSKRNL.EXE.@)
2211 HANDLE WINAPI
PsGetCurrentThreadId(void)
2213 if (GetCurrentThreadId() == request_thread
)
2214 return UlongToHandle(client_tid
);
2215 return UlongToHandle(GetCurrentThreadId());
2219 /***********************************************************************
2220 * PsGetVersion (NTOSKRNL.EXE.@)
2222 BOOLEAN WINAPI
PsGetVersion(ULONG
*major
, ULONG
*minor
, ULONG
*build
, UNICODE_STRING
*version
)
2224 RTL_OSVERSIONINFOEXW info
;
2226 info
.dwOSVersionInfoSize
= sizeof(info
);
2227 RtlGetVersion( &info
);
2228 if (major
) *major
= info
.dwMajorVersion
;
2229 if (minor
) *minor
= info
.dwMinorVersion
;
2230 if (build
) *build
= info
.dwBuildNumber
;
2234 #if 0 /* FIXME: GameGuard passes an uninitialized pointer in version->Buffer */
2235 size_t len
= min( strlenW(info
.szCSDVersion
)*sizeof(WCHAR
), version
->MaximumLength
);
2236 memcpy( version
->Buffer
, info
.szCSDVersion
, len
);
2237 if (len
< version
->MaximumLength
) version
->Buffer
[len
/ sizeof(WCHAR
)] = 0;
2238 version
->Length
= len
;
2245 /***********************************************************************
2246 * PsImpersonateClient (NTOSKRNL.EXE.@)
2248 NTSTATUS WINAPI
PsImpersonateClient(PETHREAD Thread
, PACCESS_TOKEN Token
, BOOLEAN CopyOnOpen
,
2249 BOOLEAN EffectiveOnly
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
2251 FIXME("(%p, %p, %u, %u, %u): stub\n", Thread
, Token
, CopyOnOpen
, EffectiveOnly
, ImpersonationLevel
);
2253 return STATUS_NOT_IMPLEMENTED
;
2257 /***********************************************************************
2258 * PsSetCreateProcessNotifyRoutine (NTOSKRNL.EXE.@)
2260 NTSTATUS WINAPI
PsSetCreateProcessNotifyRoutine( PCREATE_PROCESS_NOTIFY_ROUTINE callback
, BOOLEAN remove
)
2262 FIXME( "stub: %p %d\n", callback
, remove
);
2263 return STATUS_SUCCESS
;
2267 /***********************************************************************
2268 * PsSetCreateThreadNotifyRoutine (NTOSKRNL.EXE.@)
2270 NTSTATUS WINAPI
PsSetCreateThreadNotifyRoutine( PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
)
2272 FIXME( "stub: %p\n", NotifyRoutine
);
2273 return STATUS_SUCCESS
;
2277 /***********************************************************************
2278 * PsRemoveCreateThreadNotifyRoutine (NTOSKRNL.EXE.@)
2280 NTSTATUS WINAPI
PsRemoveCreateThreadNotifyRoutine( PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
)
2282 FIXME( "stub: %p\n", NotifyRoutine
);
2283 return STATUS_SUCCESS
;
2287 /***********************************************************************
2288 * PsRemoveLoadImageNotifyRoutine (NTOSKRNL.EXE.@)
2290 NTSTATUS WINAPI
PsRemoveLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
)
2292 FIXME( "stub: %p\n", NotifyRoutine
);
2293 return STATUS_SUCCESS
;
2297 /***********************************************************************
2298 * PsTerminateSystemThread (NTOSKRNL.EXE.@)
2300 NTSTATUS WINAPI
PsTerminateSystemThread(NTSTATUS ExitStatus
)
2302 FIXME( "stub: %u\n", ExitStatus
);
2303 return STATUS_NOT_IMPLEMENTED
;
2307 /***********************************************************************
2308 * MmGetSystemRoutineAddress (NTOSKRNL.EXE.@)
2310 PVOID WINAPI
MmGetSystemRoutineAddress(PUNICODE_STRING SystemRoutineName
)
2313 STRING routineNameA
;
2316 static const WCHAR ntoskrnlW
[] = {'n','t','o','s','k','r','n','l','.','e','x','e',0};
2317 static const WCHAR halW
[] = {'h','a','l','.','d','l','l',0};
2319 if (!SystemRoutineName
) return NULL
;
2321 if (RtlUnicodeStringToAnsiString( &routineNameA
, SystemRoutineName
, TRUE
) == STATUS_SUCCESS
)
2323 /* We only support functions exported from ntoskrnl.exe or hal.dll */
2324 hMod
= GetModuleHandleW( ntoskrnlW
);
2325 pFunc
= GetProcAddress( hMod
, routineNameA
.Buffer
);
2328 hMod
= GetModuleHandleW( halW
);
2329 if (hMod
) pFunc
= GetProcAddress( hMod
, routineNameA
.Buffer
);
2331 RtlFreeAnsiString( &routineNameA
);
2335 TRACE( "%s -> %p\n", debugstr_us(SystemRoutineName
), pFunc
);
2337 FIXME( "%s not found\n", debugstr_us(SystemRoutineName
) );
2342 /***********************************************************************
2343 * MmQuerySystemSize (NTOSKRNL.EXE.@)
2345 MM_SYSTEMSIZE WINAPI
MmQuerySystemSize(void)
2348 return MmLargeSystem
;
2351 /***********************************************************************
2352 * KeInitializeDpc (NTOSKRNL.EXE.@)
2354 VOID WINAPI
KeInitializeDpc(PRKDPC Dpc
, PKDEFERRED_ROUTINE DeferredRoutine
, PVOID DeferredContext
)
2359 /***********************************************************************
2360 * READ_REGISTER_BUFFER_UCHAR (NTOSKRNL.EXE.@)
2362 VOID WINAPI
READ_REGISTER_BUFFER_UCHAR(PUCHAR Register
, PUCHAR Buffer
, ULONG Count
)
2367 /*****************************************************
2368 * PoSetPowerState (NTOSKRNL.EXE.@)
2370 POWER_STATE WINAPI
PoSetPowerState(PDEVICE_OBJECT DeviceObject
, POWER_STATE_TYPE Type
, POWER_STATE State
)
2372 FIXME("(%p %u %u) stub\n", DeviceObject
, Type
, State
.DeviceState
);
2376 /*****************************************************
2377 * IoWMIRegistrationControl (NTOSKRNL.EXE.@)
2379 NTSTATUS WINAPI
IoWMIRegistrationControl(PDEVICE_OBJECT DeviceObject
, ULONG Action
)
2381 FIXME("(%p %u) stub\n", DeviceObject
, Action
);
2382 return STATUS_SUCCESS
;
2385 /*****************************************************
2386 * PsSetLoadImageNotifyRoutine (NTOSKRNL.EXE.@)
2388 NTSTATUS WINAPI
PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine
)
2390 FIXME("(%p) stub\n", routine
);
2391 return STATUS_SUCCESS
;
2394 /*****************************************************
2395 * PsLookupProcessByProcessId (NTOSKRNL.EXE.@)
2397 NTSTATUS WINAPI
PsLookupProcessByProcessId(HANDLE processid
, PEPROCESS
*process
)
2400 if (!once
++) FIXME("(%p %p) stub\n", processid
, process
);
2401 return STATUS_NOT_IMPLEMENTED
;
2405 /*****************************************************
2406 * IoSetThreadHardErrorMode (NTOSKRNL.EXE.@)
2408 BOOLEAN WINAPI
IoSetThreadHardErrorMode(BOOLEAN EnableHardErrors
)
2415 /*****************************************************
2416 * IoInitializeRemoveLockEx (NTOSKRNL.EXE.@)
2418 VOID WINAPI
IoInitializeRemoveLockEx(PIO_REMOVE_LOCK lock
, ULONG tag
,
2419 ULONG maxmin
, ULONG high
, ULONG size
)
2421 FIXME("(%p %u %u %u %u) stub\n", lock
, tag
, maxmin
, high
, size
);
2425 /*****************************************************
2426 * IoAcquireRemoveLockEx (NTOSKRNL.EXE.@)
2429 NTSTATUS WINAPI
IoAcquireRemoveLockEx(PIO_REMOVE_LOCK lock
, PVOID tag
,
2430 LPCSTR file
, ULONG line
, ULONG lock_size
)
2432 FIXME("(%p, %p, %s, %u, %u): stub\n", lock
, tag
, debugstr_a(file
), line
, lock_size
);
2434 return STATUS_NOT_IMPLEMENTED
;
2438 /*****************************************************
2441 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
2443 static void *handler
;
2444 LARGE_INTEGER count
;
2448 case DLL_PROCESS_ATTACH
:
2449 DisableThreadLibraryCalls( inst
);
2450 if (wine_rb_init( &wine_drivers
, &wine_drivers_rb_functions
)) return FALSE
;
2451 #if defined(__i386__) || defined(__x86_64__)
2452 handler
= RtlAddVectoredExceptionHandler( TRUE
, vectored_handler
);
2454 KeQueryTickCount( &count
); /* initialize the global KeTickCount */
2456 case DLL_PROCESS_DETACH
:
2457 if (reserved
) break;
2458 RtlRemoveVectoredExceptionHandler( handler
);
2464 /*****************************************************
2465 * Ke386IoSetAccessProcess (NTOSKRNL.EXE.@)
2467 BOOLEAN WINAPI
Ke386IoSetAccessProcess(PEPROCESS
*process
, ULONG flag
)
2469 FIXME("(%p %d) stub\n", process
, flag
);
2473 /*****************************************************
2474 * Ke386SetIoAccessMap (NTOSKRNL.EXE.@)
2476 BOOLEAN WINAPI
Ke386SetIoAccessMap(ULONG flag
, PVOID buffer
)
2478 FIXME("(%d %p) stub\n", flag
, buffer
);
2482 /*****************************************************
2483 * IoCreateSynchronizationEvent (NTOSKRNL.EXE.@)
2485 PKEVENT WINAPI
IoCreateSynchronizationEvent(PUNICODE_STRING name
, PHANDLE handle
)
2487 FIXME("(%p %p) stub\n", name
, handle
);
2491 /*****************************************************
2492 * IoStartNextPacket (NTOSKRNL.EXE.@)
2494 VOID WINAPI
IoStartNextPacket(PDEVICE_OBJECT deviceobject
, BOOLEAN cancelable
)
2496 FIXME("(%p %d) stub\n", deviceobject
, cancelable
);
2499 /*****************************************************
2500 * ObQueryNameString (NTOSKRNL.EXE.@)
2502 NTSTATUS WINAPI
ObQueryNameString(PVOID object
, POBJECT_NAME_INFORMATION name
, ULONG maxlength
, PULONG returnlength
)
2504 FIXME("(%p %p %u %p) stub\n", object
, name
, maxlength
, returnlength
);
2505 return STATUS_NOT_IMPLEMENTED
;
2508 /*****************************************************
2509 * IoRegisterPlugPlayNotification (NTOSKRNL.EXE.@)
2511 NTSTATUS WINAPI
IoRegisterPlugPlayNotification(IO_NOTIFICATION_EVENT_CATEGORY category
, ULONG flags
, PVOID data
,
2512 PDRIVER_OBJECT driver
, PDRIVER_NOTIFICATION_CALLBACK_ROUTINE callback
,
2513 PVOID context
, PVOID
*notification
)
2515 FIXME("(%u %u %p %p %p %p %p) stub\n", category
, flags
, data
, driver
, callback
, context
, notification
);
2516 return STATUS_SUCCESS
;
2519 /*****************************************************
2520 * IoCsqInitialize (NTOSKRNL.EXE.@)
2522 NTSTATUS WINAPI
IoCsqInitialize(PIO_CSQ csq
, PIO_CSQ_INSERT_IRP insert_irp
, PIO_CSQ_REMOVE_IRP remove_irp
,
2523 PIO_CSQ_PEEK_NEXT_IRP peek_irp
, PIO_CSQ_ACQUIRE_LOCK acquire_lock
,
2524 PIO_CSQ_RELEASE_LOCK release_lock
, PIO_CSQ_COMPLETE_CANCELED_IRP complete_irp
)
2526 FIXME("(%p %p %p %p %p %p %p) stub\n",
2527 csq
, insert_irp
, remove_irp
, peek_irp
, acquire_lock
, release_lock
, complete_irp
);
2528 return STATUS_SUCCESS
;
2531 /***********************************************************************
2532 * ExAcquireResourceExclusiveLite (NTOSKRNL.EXE.@)
2534 BOOLEAN WINAPI
ExAcquireResourceExclusiveLite( PERESOURCE resource
, BOOLEAN wait
)
2536 FIXME( ":%p %u stub\n", resource
, wait
);
2540 /***********************************************************************
2541 * ExDeleteResourceLite (NTOSKRNL.EXE.@)
2543 NTSTATUS WINAPI
ExDeleteResourceLite(PERESOURCE resource
)
2545 FIXME("(%p): stub\n", resource
);
2546 return STATUS_NOT_IMPLEMENTED
;
2549 /*****************************************************
2550 * ExInterlockedRemoveHeadList (NTOSKRNL.EXE.@)
2552 PLIST_ENTRY WINAPI
ExInterlockedRemoveHeadList(PLIST_ENTRY head
, PKSPIN_LOCK lock
)
2554 FIXME("(%p %p) stub\n", head
, lock
);
2558 /***********************************************************************
2559 * ExfInterlockedRemoveHeadList (NTOSKRNL.EXE.@)
2561 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
2562 DEFINE_FASTCALL2_ENTRYPOINT( ExfInterlockedRemoveHeadList
)
2563 PLIST_ENTRY WINAPI
__regs_ExfInterlockedRemoveHeadList(PLIST_ENTRY head
, PKSPIN_LOCK lock
)
2565 PLIST_ENTRY WINAPI
ExfInterlockedRemoveHeadList(PLIST_ENTRY head
, PKSPIN_LOCK lock
)
2568 FIXME("(%p %p) stub\n", head
, lock
);
2569 return ExInterlockedRemoveHeadList( head
, lock
);
2572 /***********************************************************************
2573 * ExReleaseResourceForThreadLite (NTOSKRNL.EXE.@)
2575 void WINAPI
ExReleaseResourceForThreadLite( PERESOURCE resource
, ERESOURCE_THREAD tid
)
2577 FIXME( "stub: %p %lu\n", resource
, tid
);
2580 /***********************************************************************
2581 * KeEnterCriticalRegion (NTOSKRNL.EXE.@)
2583 void WINAPI
KeEnterCriticalRegion(void)
2588 /***********************************************************************
2589 * KeLeaveCriticalRegion (NTOSKRNL.EXE.@)
2591 void WINAPI
KeLeaveCriticalRegion(void)
2596 /***********************************************************************
2597 * ProbeForRead (NTOSKRNL.EXE.@)
2599 void WINAPI
ProbeForRead(void *address
, SIZE_T length
, ULONG alignment
)
2601 FIXME("(%p %lu %u) stub\n", address
, length
, alignment
);
2604 /***********************************************************************
2605 * ProbeForWrite (NTOSKRNL.EXE.@)
2607 void WINAPI
ProbeForWrite(void *address
, SIZE_T length
, ULONG alignment
)
2609 FIXME("(%p %lu %u) stub\n", address
, length
, alignment
);
2612 /***********************************************************************
2613 * CmRegisterCallback (NTOSKRNL.EXE.@)
2615 NTSTATUS WINAPI
CmRegisterCallback(EX_CALLBACK_FUNCTION
*function
, void *context
, LARGE_INTEGER
*cookie
)
2617 FIXME("(%p %p %p): stub\n", function
, context
, cookie
);
2618 return STATUS_NOT_IMPLEMENTED
;
2621 /***********************************************************************
2622 * CmUnRegisterCallback (NTOSKRNL.EXE.@)
2624 NTSTATUS WINAPI
CmUnRegisterCallback(LARGE_INTEGER cookie
)
2626 FIXME("(%s): stub\n", wine_dbgstr_longlong(cookie
.QuadPart
));
2627 return STATUS_NOT_IMPLEMENTED
;
2630 /***********************************************************************
2631 * KeDelayExecutionThread (NTOSKRNL.EXE.@)
2633 NTSTATUS WINAPI
KeDelayExecutionThread(KPROCESSOR_MODE waitmode
, BOOLEAN alertable
, PLARGE_INTEGER interval
)
2635 FIXME("(%u, %u, %p): stub\n", waitmode
, alertable
, interval
);
2636 return STATUS_NOT_IMPLEMENTED
;
2639 /***********************************************************************
2640 * IoAttachDevice (NTOSKRNL.EXE.@)
2642 NTSTATUS WINAPI
IoAttachDevice(DEVICE_OBJECT
*source
, UNICODE_STRING
*target
, DEVICE_OBJECT
*attached
)
2644 FIXME("(%p, %s, %p): stub\n", source
, debugstr_us(target
), attached
);
2645 return STATUS_NOT_IMPLEMENTED
;
2649 static NTSTATUS
open_driver( const UNICODE_STRING
*service_name
, SC_HANDLE
*service
)
2651 QUERY_SERVICE_CONFIGW
*service_config
= NULL
;
2652 SC_HANDLE manager_handle
;
2653 DWORD config_size
= 0;
2656 if (!(name
= RtlAllocateHeap( GetProcessHeap(), 0, service_name
->Length
+ sizeof(WCHAR
) )))
2657 return STATUS_NO_MEMORY
;
2659 memcpy( name
, service_name
->Buffer
, service_name
->Length
);
2660 name
[ service_name
->Length
/ sizeof(WCHAR
) ] = 0;
2662 if (strncmpW( name
, servicesW
, strlenW(servicesW
) ))
2664 FIXME( "service name %s is not a keypath\n", debugstr_us(service_name
) );
2665 RtlFreeHeap( GetProcessHeap(), 0, name
);
2666 return STATUS_NOT_IMPLEMENTED
;
2669 if (!(manager_handle
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_CONNECT
)))
2671 WARN( "failed to connect to service manager\n" );
2672 RtlFreeHeap( GetProcessHeap(), 0, name
);
2673 return STATUS_NOT_SUPPORTED
;
2676 *service
= OpenServiceW( manager_handle
, name
+ strlenW(servicesW
), SERVICE_ALL_ACCESS
);
2677 RtlFreeHeap( GetProcessHeap(), 0, name
);
2678 CloseServiceHandle( manager_handle
);
2682 WARN( "failed to open service %s\n", debugstr_us(service_name
) );
2683 return STATUS_UNSUCCESSFUL
;
2686 QueryServiceConfigW( *service
, NULL
, 0, &config_size
);
2687 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
2689 WARN( "failed to query service config\n" );
2693 if (!(service_config
= RtlAllocateHeap( GetProcessHeap(), 0, config_size
)))
2696 if (!QueryServiceConfigW( *service
, service_config
, config_size
, &config_size
))
2698 WARN( "failed to query service config\n" );
2702 if (service_config
->dwServiceType
!= SERVICE_KERNEL_DRIVER
&&
2703 service_config
->dwServiceType
!= SERVICE_FILE_SYSTEM_DRIVER
)
2705 WARN( "service %s is not a kernel driver\n", debugstr_us(service_name
) );
2709 TRACE( "opened service for driver %s\n", debugstr_us(service_name
) );
2710 RtlFreeHeap( GetProcessHeap(), 0, service_config
);
2711 return STATUS_SUCCESS
;
2714 CloseServiceHandle( *service
);
2715 RtlFreeHeap( GetProcessHeap(), 0, service_config
);
2716 return STATUS_UNSUCCESSFUL
;
2720 /***********************************************************************
2721 * ZwLoadDriver (NTOSKRNL.EXE.@)
2723 NTSTATUS WINAPI
ZwLoadDriver( const UNICODE_STRING
*service_name
)
2725 SERVICE_STATUS_PROCESS service_status
;
2726 SC_HANDLE service_handle
;
2731 TRACE( "(%s)\n", debugstr_us(service_name
) );
2733 if ((status
= open_driver( service_name
, &service_handle
)) != STATUS_SUCCESS
)
2736 TRACE( "trying to start %s\n", debugstr_us(service_name
) );
2738 for (i
= 0; i
< 100; i
++) /* 10 sec timeout */
2740 if (StartServiceW( service_handle
, 0, NULL
)) break;
2741 if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING
) break;
2742 if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED
) goto error
;
2745 if (i
== 100) goto error
;
2747 for (i
= 0; i
< 100; i
++) /* 10 sec timeout */
2749 if (!QueryServiceStatusEx( service_handle
, SC_STATUS_PROCESS_INFO
,
2750 (BYTE
*)&service_status
, sizeof(service_status
), &bytes
)) goto error
;
2751 if (service_status
.dwCurrentState
!= SERVICE_START_PENDING
) break;
2755 if (service_status
.dwCurrentState
== SERVICE_RUNNING
)
2757 if (service_status
.dwProcessId
!= GetCurrentProcessId())
2758 FIXME( "driver %s was loaded into a different process\n", debugstr_us(service_name
) );
2760 status
= STATUS_SUCCESS
;
2765 WARN( "failed to start service %s\n", debugstr_us(service_name
) );
2766 status
= STATUS_UNSUCCESSFUL
;
2769 TRACE( "returning status %08x\n", status
);
2770 CloseServiceHandle( service_handle
);
2775 /***********************************************************************
2776 * ZwUnloadDriver (NTOSKRNL.EXE.@)
2778 NTSTATUS WINAPI
ZwUnloadDriver( const UNICODE_STRING
*service_name
)
2780 SERVICE_STATUS service_status
;
2781 SC_HANDLE service_handle
;
2785 TRACE( "(%s)\n", debugstr_us(service_name
) );
2787 if ((status
= open_driver( service_name
, &service_handle
)) != STATUS_SUCCESS
)
2790 if (!ControlService( service_handle
, SERVICE_CONTROL_STOP
, &service_status
))
2793 for (i
= 0; i
< 100; i
++) /* 10 sec timeout */
2795 if (!QueryServiceStatus( service_handle
, &service_status
)) goto error
;
2796 if (service_status
.dwCurrentState
!= SERVICE_STOP_PENDING
) break;
2800 if (service_status
.dwCurrentState
== SERVICE_STOPPED
)
2802 status
= STATUS_SUCCESS
;
2807 WARN( "failed to stop service %s\n", debugstr_us(service_name
) );
2808 status
= STATUS_UNSUCCESSFUL
;
2811 TRACE( "returning status %08x\n", status
);
2812 CloseServiceHandle( service_handle
);