2 * ntoskrnl.exe implementation
4 * Copyright (C) 2007 Alexandre Julliard
5 * Copyright (C) 2010 Damjan Jovanovic
6 * Copyright (C) 2016 Sebastian Lackner
7 * Copyright (C) 2016 CodeWeavers, Aric Stewart
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/port.h"
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
33 #define WIN32_NO_STATUS
40 #include "ddk/ntddk.h"
41 #include "ddk/ntifs.h"
43 #include "wine/unicode.h"
44 #include "wine/server.h"
45 #include "wine/debug.h"
47 #include "wine/rbtree.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl
);
50 WINE_DECLARE_DEBUG_CHANNEL(relay
);
52 BOOLEAN KdDebuggerEnabled
= FALSE
;
53 ULONG InitSafeBootMode
= 0;
55 extern LONG CALLBACK
vectored_handler( EXCEPTION_POINTERS
*ptrs
);
57 KSYSTEM_TIME KeTickCount
= { 0, 0, 0 };
59 typedef struct _KSERVICE_TABLE_DESCRIPTOR
65 } KSERVICE_TABLE_DESCRIPTOR
, *PKSERVICE_TABLE_DESCRIPTOR
;
67 KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable
[4] = { { 0 } };
69 typedef void (WINAPI
*PCREATE_PROCESS_NOTIFY_ROUTINE
)(HANDLE
,HANDLE
,BOOLEAN
);
70 typedef void (WINAPI
*PCREATE_THREAD_NOTIFY_ROUTINE
)(HANDLE
,HANDLE
,BOOLEAN
);
72 static const WCHAR servicesW
[] = {'\\','R','e','g','i','s','t','r','y',
73 '\\','M','a','c','h','i','n','e',
74 '\\','S','y','s','t','e','m',
75 '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
76 '\\','S','e','r','v','i','c','e','s',
79 /* tid of the thread running client request */
80 static DWORD request_thread
;
82 /* pid/tid of the client thread */
83 static DWORD client_tid
;
84 static DWORD client_pid
;
88 struct wine_rb_entry entry
;
90 DRIVER_OBJECT driver_obj
;
91 DRIVER_EXTENSION driver_extension
;
94 static int wine_drivers_rb_compare( const void *key
, const struct wine_rb_entry
*entry
)
96 const struct wine_driver
*driver
= WINE_RB_ENTRY_VALUE( entry
, const struct wine_driver
, entry
);
97 const UNICODE_STRING
*k
= key
;
99 return RtlCompareUnicodeString( k
, &driver
->driver_obj
.DriverName
, FALSE
);
102 static struct wine_rb_tree wine_drivers
= { wine_drivers_rb_compare
};
104 static CRITICAL_SECTION drivers_cs
;
105 static CRITICAL_SECTION_DEBUG critsect_debug
=
108 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
109 0, 0, { (DWORD_PTR
)(__FILE__
": drivers_cs") }
111 static CRITICAL_SECTION drivers_cs
= { &critsect_debug
, -1, 0, 0, 0, 0 };
114 #define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
115 __ASM_STDCALL_FUNC( name, 4, \
119 "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(4))
120 #define DEFINE_FASTCALL2_ENTRYPOINT( name ) \
121 __ASM_STDCALL_FUNC( name, 8, \
126 "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(8))
127 #define DEFINE_FASTCALL3_ENTRYPOINT( name ) \
128 __ASM_STDCALL_FUNC( name, 12, \
133 "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(12))
136 static inline LPCSTR
debugstr_us( const UNICODE_STRING
*us
)
138 if (!us
) return "<null>";
139 return debugstr_wn( us
->Buffer
, us
->Length
/ sizeof(WCHAR
) );
142 static HANDLE
get_device_manager(void)
144 static HANDLE device_manager
;
145 HANDLE handle
= 0, ret
= device_manager
;
149 SERVER_START_REQ( create_device_manager
)
151 req
->access
= SYNCHRONIZE
;
153 if (!wine_server_call( req
)) handle
= wine_server_ptr_handle( reply
->handle
);
159 ERR( "failed to create the device manager\n" );
162 if (!(ret
= InterlockedCompareExchangePointer( &device_manager
, handle
, 0 )))
165 NtClose( handle
); /* somebody beat us to it */
170 static NTSTATUS
dispatch_irp( DEVICE_OBJECT
*device
, IRP
*irp
)
174 KeQueryTickCount( &count
); /* update the global KeTickCount */
176 device
->CurrentIrp
= irp
;
178 IoCallDriver( device
, irp
);
180 device
->CurrentIrp
= NULL
;
182 return STATUS_SUCCESS
;
185 /* process a create request for a given file */
186 static NTSTATUS
dispatch_create( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
187 ULONG out_size
, HANDLE irp_handle
)
190 IO_STACK_LOCATION
*irpsp
;
192 DEVICE_OBJECT
*device
= wine_server_get_ptr( params
->create
.device
);
194 if (!(file
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*file
) ))) return STATUS_NO_MEMORY
;
196 TRACE( "device %p -> file %p\n", device
, file
);
198 file
->Type
= 5; /* MSDN */
199 file
->Size
= sizeof(*file
);
200 file
->DeviceObject
= device
;
202 if (!(irp
= IoAllocateIrp( device
->StackSize
, FALSE
)))
204 HeapFree( GetProcessHeap(), 0, file
);
205 return STATUS_NO_MEMORY
;
208 irpsp
= IoGetNextIrpStackLocation( irp
);
209 irpsp
->MajorFunction
= IRP_MJ_CREATE
;
210 irpsp
->DeviceObject
= device
;
211 irpsp
->CompletionRoutine
= NULL
;
212 irpsp
->Parameters
.Create
.SecurityContext
= NULL
; /* FIXME */
213 irpsp
->Parameters
.Create
.Options
= params
->create
.options
;
214 irpsp
->Parameters
.Create
.ShareAccess
= params
->create
.sharing
;
215 irpsp
->Parameters
.Create
.FileAttributes
= 0;
216 irpsp
->Parameters
.Create
.EaLength
= 0;
218 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
219 irp
->RequestorMode
= UserMode
;
220 irp
->AssociatedIrp
.SystemBuffer
= NULL
;
221 irp
->UserBuffer
= NULL
;
222 irp
->UserIosb
= irp_handle
; /* note: we abuse UserIosb to store the server irp handle */
223 irp
->UserEvent
= NULL
;
225 if (device
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
]) return dispatch_irp( device
, irp
);
227 irp
->IoStatus
.u
.Status
= STATUS_SUCCESS
;
228 IoCompleteRequest( irp
, IO_NO_INCREMENT
);
229 return STATUS_SUCCESS
;
232 /* process a close request for a given file */
233 static NTSTATUS
dispatch_close( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
234 ULONG out_size
, HANDLE irp_handle
)
237 IO_STACK_LOCATION
*irpsp
;
238 DEVICE_OBJECT
*device
;
239 FILE_OBJECT
*file
= wine_server_get_ptr( params
->close
.file
);
241 if (!file
) return STATUS_INVALID_HANDLE
;
243 device
= file
->DeviceObject
;
245 TRACE( "device %p file %p\n", device
, file
);
247 if (!(irp
= IoAllocateIrp( device
->StackSize
, FALSE
)))
249 HeapFree( GetProcessHeap(), 0, file
);
250 return STATUS_NO_MEMORY
;
253 irpsp
= IoGetNextIrpStackLocation( irp
);
254 irpsp
->MajorFunction
= IRP_MJ_CLOSE
;
255 irpsp
->DeviceObject
= device
;
256 irpsp
->CompletionRoutine
= NULL
;
257 irpsp
->Parameters
.Create
.SecurityContext
= NULL
; /* FIXME */
258 irpsp
->Parameters
.Create
.Options
= params
->create
.options
;
259 irpsp
->Parameters
.Create
.ShareAccess
= params
->create
.sharing
;
260 irpsp
->Parameters
.Create
.FileAttributes
= 0;
261 irpsp
->Parameters
.Create
.EaLength
= 0;
263 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
264 irp
->RequestorMode
= UserMode
;
265 irp
->AssociatedIrp
.SystemBuffer
= NULL
;
266 irp
->UserBuffer
= NULL
;
267 irp
->UserIosb
= irp_handle
; /* note: we abuse UserIosb to store the server irp handle */
268 irp
->UserEvent
= NULL
;
270 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
])
272 irp
->IoStatus
.u
.Status
= STATUS_SUCCESS
;
273 IoCompleteRequest( irp
, IO_NO_INCREMENT
);
275 else dispatch_irp( device
, irp
);
277 HeapFree( GetProcessHeap(), 0, file
); /* FIXME: async close processing not supported */
278 return STATUS_SUCCESS
;
281 /* process a read request for a given device */
282 static NTSTATUS
dispatch_read( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
283 ULONG out_size
, HANDLE irp_handle
)
287 LARGE_INTEGER offset
;
288 IO_STACK_LOCATION
*irpsp
;
289 DEVICE_OBJECT
*device
;
290 FILE_OBJECT
*file
= wine_server_get_ptr( params
->read
.file
);
292 if (!file
) return STATUS_INVALID_HANDLE
;
294 device
= file
->DeviceObject
;
295 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_READ
]) return STATUS_NOT_SUPPORTED
;
297 TRACE( "device %p file %p size %u\n", device
, file
, out_size
);
299 if (!(out_buff
= HeapAlloc( GetProcessHeap(), 0, out_size
))) return STATUS_NO_MEMORY
;
301 offset
.QuadPart
= params
->read
.pos
;
303 /* note: we abuse UserIosb to store the server irp handle */
304 if (!(irp
= IoBuildSynchronousFsdRequest( IRP_MJ_READ
, device
, out_buff
, out_size
,
305 &offset
, NULL
, irp_handle
)))
307 HeapFree( GetProcessHeap(), 0, out_buff
);
308 return STATUS_NO_MEMORY
;
311 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
312 irp
->RequestorMode
= UserMode
;
314 irpsp
= IoGetNextIrpStackLocation( irp
);
315 irpsp
->Parameters
.Read
.Key
= params
->read
.key
;
317 return dispatch_irp( device
, irp
);
320 /* process a write request for a given device */
321 static NTSTATUS
dispatch_write( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
322 ULONG out_size
, HANDLE irp_handle
)
325 LARGE_INTEGER offset
;
326 IO_STACK_LOCATION
*irpsp
;
327 DEVICE_OBJECT
*device
;
328 FILE_OBJECT
*file
= wine_server_get_ptr( params
->write
.file
);
330 if (!file
) return STATUS_INVALID_HANDLE
;
332 device
= file
->DeviceObject
;
333 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_WRITE
]) return STATUS_NOT_SUPPORTED
;
335 TRACE( "device %p file %p size %u\n", device
, file
, in_size
);
337 offset
.QuadPart
= params
->write
.pos
;
339 /* note: we abuse UserIosb to store the server irp handle */
340 if (!(irp
= IoBuildSynchronousFsdRequest( IRP_MJ_WRITE
, device
, in_buff
, in_size
,
341 &offset
, NULL
, irp_handle
)))
342 return STATUS_NO_MEMORY
;
344 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
345 irp
->RequestorMode
= UserMode
;
347 irpsp
= IoGetNextIrpStackLocation( irp
);
348 irpsp
->Parameters
.Write
.Key
= params
->write
.key
;
350 return dispatch_irp( device
, irp
);
353 /* process a flush request for a given device */
354 static NTSTATUS
dispatch_flush( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
355 ULONG out_size
, HANDLE irp_handle
)
358 DEVICE_OBJECT
*device
;
359 FILE_OBJECT
*file
= wine_server_get_ptr( params
->flush
.file
);
361 if (!file
) return STATUS_INVALID_HANDLE
;
363 device
= file
->DeviceObject
;
364 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
]) return STATUS_NOT_SUPPORTED
;
366 TRACE( "device %p file %p\n", device
, file
);
368 /* note: we abuse UserIosb to store the server irp handle */
369 if (!(irp
= IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS
, device
, in_buff
, in_size
,
370 NULL
, NULL
, irp_handle
)))
371 return STATUS_NO_MEMORY
;
373 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
374 irp
->RequestorMode
= UserMode
;
376 return dispatch_irp( device
, irp
);
379 /* process an ioctl request for a given device */
380 static NTSTATUS
dispatch_ioctl( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
381 ULONG out_size
, HANDLE irp_handle
)
384 void *out_buff
= NULL
;
385 DEVICE_OBJECT
*device
;
386 FILE_OBJECT
*file
= wine_server_get_ptr( params
->ioctl
.file
);
388 if (!file
) return STATUS_INVALID_HANDLE
;
390 device
= file
->DeviceObject
;
391 if (!device
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
]) return STATUS_NOT_SUPPORTED
;
393 TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n",
394 params
->ioctl
.code
, device
, file
, in_size
, out_size
);
396 if ((params
->ioctl
.code
& 3) == METHOD_BUFFERED
) out_size
= max( in_size
, out_size
);
400 if (!(out_buff
= HeapAlloc( GetProcessHeap(), 0, out_size
))) return STATUS_NO_MEMORY
;
401 if ((params
->ioctl
.code
& 3) == METHOD_BUFFERED
)
403 memcpy( out_buff
, in_buff
, in_size
);
408 /* note: we abuse UserIosb to store the server handle to the ioctl */
409 irp
= IoBuildDeviceIoControlRequest( params
->ioctl
.code
, device
, in_buff
, in_size
, out_buff
, out_size
,
410 FALSE
, NULL
, irp_handle
);
413 HeapFree( GetProcessHeap(), 0, out_buff
);
414 return STATUS_NO_MEMORY
;
417 irp
->Tail
.Overlay
.OriginalFileObject
= file
;
418 irp
->RequestorMode
= UserMode
;
420 return dispatch_irp( device
, irp
);
423 typedef NTSTATUS (*dispatch_func
)( const irp_params_t
*params
, void *in_buff
, ULONG in_size
,
424 ULONG out_size
, HANDLE irp_handle
);
426 static const dispatch_func dispatch_funcs
[IRP_MJ_MAXIMUM_FUNCTION
+ 1] =
428 dispatch_create
, /* IRP_MJ_CREATE */
429 NULL
, /* IRP_MJ_CREATE_NAMED_PIPE */
430 dispatch_close
, /* IRP_MJ_CLOSE */
431 dispatch_read
, /* IRP_MJ_READ */
432 dispatch_write
, /* IRP_MJ_WRITE */
433 NULL
, /* IRP_MJ_QUERY_INFORMATION */
434 NULL
, /* IRP_MJ_SET_INFORMATION */
435 NULL
, /* IRP_MJ_QUERY_EA */
436 NULL
, /* IRP_MJ_SET_EA */
437 dispatch_flush
, /* IRP_MJ_FLUSH_BUFFERS */
438 NULL
, /* IRP_MJ_QUERY_VOLUME_INFORMATION */
439 NULL
, /* IRP_MJ_SET_VOLUME_INFORMATION */
440 NULL
, /* IRP_MJ_DIRECTORY_CONTROL */
441 NULL
, /* IRP_MJ_FILE_SYSTEM_CONTROL */
442 dispatch_ioctl
, /* IRP_MJ_DEVICE_CONTROL */
443 NULL
, /* IRP_MJ_INTERNAL_DEVICE_CONTROL */
444 NULL
, /* IRP_MJ_SHUTDOWN */
445 NULL
, /* IRP_MJ_LOCK_CONTROL */
446 NULL
, /* IRP_MJ_CLEANUP */
447 NULL
, /* IRP_MJ_CREATE_MAILSLOT */
448 NULL
, /* IRP_MJ_QUERY_SECURITY */
449 NULL
, /* IRP_MJ_SET_SECURITY */
450 NULL
, /* IRP_MJ_POWER */
451 NULL
, /* IRP_MJ_SYSTEM_CONTROL */
452 NULL
, /* IRP_MJ_DEVICE_CHANGE */
453 NULL
, /* IRP_MJ_QUERY_QUOTA */
454 NULL
, /* IRP_MJ_SET_QUOTA */
455 NULL
, /* IRP_MJ_PNP */
459 /***********************************************************************
460 * wine_ntoskrnl_main_loop (Not a Windows API)
462 NTSTATUS CDECL
wine_ntoskrnl_main_loop( HANDLE stop_event
)
464 HANDLE manager
= get_device_manager();
466 NTSTATUS status
= STATUS_SUCCESS
;
467 irp_params_t irp_params
;
469 ULONG in_size
= 4096, out_size
= 0;
472 request_thread
= GetCurrentThreadId();
474 if (!(in_buff
= HeapAlloc( GetProcessHeap(), 0, in_size
)))
476 ERR( "failed to allocate buffer\n" );
477 return STATUS_NO_MEMORY
;
480 handles
[0] = stop_event
;
481 handles
[1] = manager
;
485 SERVER_START_REQ( get_next_device_request
)
487 req
->manager
= wine_server_obj_handle( manager
);
488 req
->prev
= wine_server_obj_handle( irp
);
489 req
->status
= status
;
490 wine_server_set_reply( req
, in_buff
, in_size
);
491 if (!(status
= wine_server_call( req
)))
493 irp
= wine_server_ptr_handle( reply
->next
);
494 irp_params
= reply
->params
;
495 client_tid
= reply
->client_tid
;
496 client_pid
= reply
->client_pid
;
497 in_size
= reply
->in_size
;
498 out_size
= reply
->out_size
;
502 irp
= 0; /* no previous irp */
504 in_size
= reply
->in_size
;
512 if (irp_params
.major
> IRP_MJ_MAXIMUM_FUNCTION
|| !dispatch_funcs
[irp_params
.major
])
514 WARN( "unsupported request %u\n", irp_params
.major
);
515 status
= STATUS_NOT_SUPPORTED
;
518 status
= dispatch_funcs
[irp_params
.major
]( &irp_params
, in_buff
, in_size
, out_size
, irp
);
519 if (status
== STATUS_SUCCESS
) irp
= 0; /* status reported by IoCompleteRequest */
521 case STATUS_BUFFER_OVERFLOW
:
522 HeapFree( GetProcessHeap(), 0, in_buff
);
523 in_buff
= HeapAlloc( GetProcessHeap(), 0, in_size
);
524 /* restart with larger buffer */
529 DWORD ret
= WaitForMultipleObjectsEx( 2, handles
, FALSE
, INFINITE
, TRUE
);
530 if (ret
== WAIT_OBJECT_0
)
532 HeapFree( GetProcessHeap(), 0, in_buff
);
533 return STATUS_SUCCESS
;
535 if (ret
!= WAIT_IO_COMPLETION
) break;
543 /***********************************************************************
544 * IoAcquireCancelSpinLock (NTOSKRNL.EXE.@)
546 void WINAPI
IoAcquireCancelSpinLock(PKIRQL irql
)
548 FIXME("(%p): stub\n", irql
);
552 /***********************************************************************
553 * IoReleaseCancelSpinLock (NTOSKRNL.EXE.@)
555 void WINAPI
IoReleaseCancelSpinLock(PKIRQL irql
)
557 FIXME("(%p): stub\n", irql
);
561 /***********************************************************************
562 * IoAllocateDriverObjectExtension (NTOSKRNL.EXE.@)
564 NTSTATUS WINAPI
IoAllocateDriverObjectExtension( PDRIVER_OBJECT DriverObject
,
565 PVOID ClientIdentificationAddress
,
566 ULONG DriverObjectExtensionSize
,
567 PVOID
*DriverObjectExtension
)
569 FIXME( "stub: %p, %p, %u, %p\n", DriverObject
, ClientIdentificationAddress
,
570 DriverObjectExtensionSize
, DriverObjectExtension
);
571 return STATUS_NOT_IMPLEMENTED
;
575 /***********************************************************************
576 * IoGetDriverObjectExtension (NTOSKRNL.EXE.@)
578 PVOID WINAPI
IoGetDriverObjectExtension( PDRIVER_OBJECT DriverObject
,
579 PVOID ClientIdentificationAddress
)
581 FIXME( "stub: %p, %p\n", DriverObject
, ClientIdentificationAddress
);
586 /***********************************************************************
587 * IoInitializeIrp (NTOSKRNL.EXE.@)
589 void WINAPI
IoInitializeIrp( IRP
*irp
, USHORT size
, CCHAR stack_size
)
591 TRACE( "%p, %u, %d\n", irp
, size
, stack_size
);
593 RtlZeroMemory( irp
, size
);
595 irp
->Type
= IO_TYPE_IRP
;
597 InitializeListHead( &irp
->ThreadListEntry
);
598 irp
->StackCount
= stack_size
;
599 irp
->CurrentLocation
= stack_size
+ 1;
600 irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
=
601 (PIO_STACK_LOCATION
)(irp
+ 1) + stack_size
;
605 /***********************************************************************
606 * IoInitializeTimer (NTOSKRNL.EXE.@)
608 NTSTATUS WINAPI
IoInitializeTimer(PDEVICE_OBJECT DeviceObject
,
609 PIO_TIMER_ROUTINE TimerRoutine
,
612 FIXME( "stub: %p, %p, %p\n", DeviceObject
, TimerRoutine
, Context
);
613 return STATUS_NOT_IMPLEMENTED
;
617 /***********************************************************************
618 * IoStartTimer (NTOSKRNL.EXE.@)
620 void WINAPI
IoStartTimer(PDEVICE_OBJECT DeviceObject
)
622 FIXME( "stub: %p\n", DeviceObject
);
626 /***********************************************************************
627 * IoAllocateIrp (NTOSKRNL.EXE.@)
629 PIRP WINAPI
IoAllocateIrp( CCHAR stack_size
, BOOLEAN charge_quota
)
633 CCHAR loc_count
= stack_size
;
635 TRACE( "%d, %d\n", stack_size
, charge_quota
);
637 if (loc_count
< 8 && loc_count
!= 1)
640 size
= sizeof(IRP
) + loc_count
* sizeof(IO_STACK_LOCATION
);
641 irp
= ExAllocatePool( NonPagedPool
, size
);
644 IoInitializeIrp( irp
, size
, stack_size
);
645 if (stack_size
>= 1 && stack_size
<= 8)
646 irp
->AllocationFlags
= IRP_ALLOCATED_FIXED_SIZE
;
648 irp
->AllocationFlags
|= IRP_LOOKASIDE_ALLOCATION
;
653 /***********************************************************************
654 * IoFreeIrp (NTOSKRNL.EXE.@)
656 void WINAPI
IoFreeIrp( IRP
*irp
)
660 TRACE( "%p\n", irp
);
662 mdl
= irp
->MdlAddress
;
665 MDL
*next
= mdl
->Next
;
674 /***********************************************************************
675 * IoAllocateErrorLogEntry (NTOSKRNL.EXE.@)
677 PVOID WINAPI
IoAllocateErrorLogEntry( PVOID IoObject
, UCHAR EntrySize
)
679 FIXME( "stub: %p, %u\n", IoObject
, EntrySize
);
684 /***********************************************************************
685 * IoAllocateMdl (NTOSKRNL.EXE.@)
687 PMDL WINAPI
IoAllocateMdl( PVOID va
, ULONG length
, BOOLEAN secondary
, BOOLEAN charge_quota
, IRP
*irp
)
690 ULONG_PTR address
= (ULONG_PTR
)va
;
691 ULONG_PTR page_address
;
692 SIZE_T nb_pages
, mdl_size
;
694 TRACE("(%p, %u, %i, %i, %p)\n", va
, length
, secondary
, charge_quota
, irp
);
697 FIXME("Charge quota is not yet supported\n");
699 /* FIXME: We suppose that page size is 4096 */
700 page_address
= address
& ~(4096 - 1);
701 nb_pages
= (((address
+ length
- 1) & ~(4096 - 1)) - page_address
) / 4096 + 1;
703 mdl_size
= sizeof(MDL
) + nb_pages
* sizeof(PVOID
);
705 mdl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, mdl_size
);
709 mdl
->Size
= mdl_size
;
710 mdl
->Process
= NULL
; /* FIXME: IoGetCurrentProcess */
711 mdl
->StartVa
= (PVOID
)page_address
;
712 mdl
->ByteCount
= length
;
713 mdl
->ByteOffset
= address
- page_address
;
715 if (!irp
) return mdl
;
717 if (secondary
) /* add it at the end */
719 MDL
**pmdl
= &irp
->MdlAddress
;
720 while (*pmdl
) pmdl
= &(*pmdl
)->Next
;
725 mdl
->Next
= irp
->MdlAddress
;
726 irp
->MdlAddress
= mdl
;
732 /***********************************************************************
733 * IoFreeMdl (NTOSKRNL.EXE.@)
735 void WINAPI
IoFreeMdl(PMDL mdl
)
738 HeapFree(GetProcessHeap(), 0, mdl
);
742 /***********************************************************************
743 * IoAllocateWorkItem (NTOSKRNL.EXE.@)
745 PIO_WORKITEM WINAPI
IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject
)
747 FIXME( "stub: %p\n", DeviceObject
);
752 /***********************************************************************
753 * IoAttachDeviceToDeviceStack (NTOSKRNL.EXE.@)
755 PDEVICE_OBJECT WINAPI
IoAttachDeviceToDeviceStack( DEVICE_OBJECT
*source
,
756 DEVICE_OBJECT
*target
)
758 TRACE( "%p, %p\n", source
, target
);
759 target
->AttachedDevice
= source
;
760 source
->StackSize
= target
->StackSize
+ 1;
765 /***********************************************************************
766 * IoBuildDeviceIoControlRequest (NTOSKRNL.EXE.@)
768 PIRP WINAPI
IoBuildDeviceIoControlRequest( ULONG code
, PDEVICE_OBJECT device
,
769 PVOID in_buff
, ULONG in_len
,
770 PVOID out_buff
, ULONG out_len
,
771 BOOLEAN internal
, PKEVENT event
,
772 PIO_STATUS_BLOCK iosb
)
775 PIO_STACK_LOCATION irpsp
;
777 TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
778 code
, device
, in_buff
, in_len
, out_buff
, out_len
, internal
, event
, iosb
);
783 irp
= IoAllocateIrp( device
->StackSize
, FALSE
);
787 irpsp
= IoGetNextIrpStackLocation( irp
);
788 irpsp
->MajorFunction
= internal
? IRP_MJ_INTERNAL_DEVICE_CONTROL
: IRP_MJ_DEVICE_CONTROL
;
789 irpsp
->Parameters
.DeviceIoControl
.IoControlCode
= code
;
790 irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
= in_len
;
791 irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
= out_len
;
792 irpsp
->DeviceObject
= device
;
793 irpsp
->CompletionRoutine
= NULL
;
797 case METHOD_BUFFERED
:
798 irp
->AssociatedIrp
.SystemBuffer
= in_buff
;
800 case METHOD_IN_DIRECT
:
801 case METHOD_OUT_DIRECT
:
802 irp
->AssociatedIrp
.SystemBuffer
= in_buff
;
803 IoAllocateMdl( out_buff
, out_len
, FALSE
, FALSE
, irp
);
806 irpsp
->Parameters
.DeviceIoControl
.Type3InputBuffer
= in_buff
;
810 irp
->RequestorMode
= KernelMode
;
811 irp
->UserBuffer
= out_buff
;
812 irp
->UserIosb
= iosb
;
813 irp
->UserEvent
= event
;
818 /**********************************************************
819 * IoBuildSynchronousFsdRequest (NTOSKRNL.EXE.@)
821 PIRP WINAPI
IoBuildSynchronousFsdRequest(ULONG majorfunc
, PDEVICE_OBJECT device
,
822 PVOID buffer
, ULONG length
, PLARGE_INTEGER startoffset
,
823 PKEVENT event
, PIO_STATUS_BLOCK iosb
)
826 PIO_STACK_LOCATION irpsp
;
828 TRACE("(%d %p %p %d %p %p %p)\n", majorfunc
, device
, buffer
, length
, startoffset
, event
, iosb
);
830 if (!(irp
= IoAllocateIrp( device
->StackSize
, FALSE
))) return NULL
;
832 irpsp
= IoGetNextIrpStackLocation( irp
);
833 irpsp
->MajorFunction
= majorfunc
;
834 irpsp
->DeviceObject
= device
;
835 irpsp
->CompletionRoutine
= NULL
;
837 irp
->AssociatedIrp
.SystemBuffer
= buffer
;
838 if (device
->Flags
& DO_DIRECT_IO
) IoAllocateMdl( buffer
, length
, FALSE
, FALSE
, irp
);
843 irpsp
->Parameters
.Read
.Length
= length
;
844 irpsp
->Parameters
.Read
.ByteOffset
= *startoffset
;
847 irpsp
->Parameters
.Write
.Length
= length
;
848 irpsp
->Parameters
.Write
.ByteOffset
= *startoffset
;
851 irp
->RequestorMode
= KernelMode
;
852 irp
->UserIosb
= iosb
;
853 irp
->UserEvent
= event
;
854 irp
->UserBuffer
= buffer
;
858 static void build_driver_keypath( const WCHAR
*name
, UNICODE_STRING
*keypath
)
860 static const WCHAR driverW
[] = {'\\','D','r','i','v','e','r','\\',0};
863 /* Check what prefix is present */
864 if (strncmpW( name
, servicesW
, strlenW(servicesW
) ) == 0)
866 FIXME( "Driver name %s is malformed as the keypath\n", debugstr_w(name
) );
867 RtlCreateUnicodeString( keypath
, name
);
870 if (strncmpW( name
, driverW
, strlenW(driverW
) ) == 0)
871 name
+= strlenW(driverW
);
873 FIXME( "Driver name %s does not properly begin with \\Driver\\\n", debugstr_w(name
) );
875 str
= HeapAlloc( GetProcessHeap(), 0, sizeof(servicesW
) + strlenW(name
)*sizeof(WCHAR
));
876 lstrcpyW( str
, servicesW
);
877 lstrcatW( str
, name
);
878 RtlInitUnicodeString( keypath
, str
);
882 /***********************************************************************
883 * IoCreateDriver (NTOSKRNL.EXE.@)
885 NTSTATUS WINAPI
IoCreateDriver( UNICODE_STRING
*name
, PDRIVER_INITIALIZE init
)
887 struct wine_driver
*driver
;
890 TRACE("(%s, %p)\n", debugstr_us(name
), init
);
892 if (!(driver
= RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY
,
894 return STATUS_NO_MEMORY
;
896 if ((status
= RtlDuplicateUnicodeString( 1, name
, &driver
->driver_obj
.DriverName
)))
898 RtlFreeHeap( GetProcessHeap(), 0, driver
);
902 driver
->driver_obj
.Size
= sizeof(driver
->driver_obj
);
903 driver
->driver_obj
.DriverInit
= init
;
904 driver
->driver_obj
.DriverExtension
= &driver
->driver_extension
;
905 driver
->driver_extension
.DriverObject
= &driver
->driver_obj
;
906 build_driver_keypath( driver
->driver_obj
.DriverName
.Buffer
, &driver
->driver_extension
.ServiceKeyName
);
908 status
= driver
->driver_obj
.DriverInit( &driver
->driver_obj
, &driver
->driver_extension
.ServiceKeyName
);
912 RtlFreeUnicodeString( &driver
->driver_obj
.DriverName
);
913 RtlFreeUnicodeString( &driver
->driver_extension
.ServiceKeyName
);
914 RtlFreeHeap( GetProcessHeap(), 0, driver
);
918 EnterCriticalSection( &drivers_cs
);
919 if (wine_rb_put( &wine_drivers
, &driver
->driver_obj
.DriverName
, &driver
->entry
))
920 ERR( "failed to insert driver %s in tree\n", debugstr_us(name
) );
921 LeaveCriticalSection( &drivers_cs
);
928 /***********************************************************************
929 * IoDeleteDriver (NTOSKRNL.EXE.@)
931 void WINAPI
IoDeleteDriver( DRIVER_OBJECT
*driver_object
)
933 TRACE( "(%p)\n", driver_object
);
935 EnterCriticalSection( &drivers_cs
);
936 wine_rb_remove( &wine_drivers
, &driver_object
->DriverName
);
937 LeaveCriticalSection( &drivers_cs
);
939 RtlFreeUnicodeString( &driver_object
->DriverName
);
940 RtlFreeUnicodeString( &driver_object
->DriverExtension
->ServiceKeyName
);
941 RtlFreeHeap( GetProcessHeap(), 0, CONTAINING_RECORD( driver_object
, struct wine_driver
, driver_obj
) );
945 /***********************************************************************
946 * IoCreateDevice (NTOSKRNL.EXE.@)
948 NTSTATUS WINAPI
IoCreateDevice( DRIVER_OBJECT
*driver
, ULONG ext_size
,
949 UNICODE_STRING
*name
, DEVICE_TYPE type
,
950 ULONG characteristics
, BOOLEAN exclusive
,
951 DEVICE_OBJECT
**ret_device
)
954 DEVICE_OBJECT
*device
;
956 HANDLE manager
= get_device_manager();
958 TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n",
959 driver
, ext_size
, debugstr_us(name
), type
, characteristics
, exclusive
, ret_device
);
961 if (!(device
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*device
) + ext_size
)))
962 return STATUS_NO_MEMORY
;
964 SERVER_START_REQ( create_device
)
969 req
->manager
= wine_server_obj_handle( manager
);
970 req
->user_ptr
= wine_server_client_ptr( device
);
971 if (name
) wine_server_add_data( req
, name
->Buffer
, name
->Length
);
972 if (!(status
= wine_server_call( req
))) handle
= wine_server_ptr_handle( reply
->handle
);
976 if (status
== STATUS_SUCCESS
)
978 device
->DriverObject
= driver
;
979 device
->DeviceExtension
= device
+ 1;
980 device
->DeviceType
= type
;
981 device
->StackSize
= 1;
982 device
->Reserved
= handle
;
984 device
->NextDevice
= driver
->DeviceObject
;
985 driver
->DeviceObject
= device
;
987 *ret_device
= device
;
989 else HeapFree( GetProcessHeap(), 0, device
);
995 /***********************************************************************
996 * IoDeleteDevice (NTOSKRNL.EXE.@)
998 void WINAPI
IoDeleteDevice( DEVICE_OBJECT
*device
)
1002 TRACE( "%p\n", device
);
1004 SERVER_START_REQ( delete_device
)
1006 req
->handle
= wine_server_obj_handle( device
->Reserved
);
1007 status
= wine_server_call( req
);
1011 if (status
== STATUS_SUCCESS
)
1013 DEVICE_OBJECT
**prev
= &device
->DriverObject
->DeviceObject
;
1014 while (*prev
&& *prev
!= device
) prev
= &(*prev
)->NextDevice
;
1015 if (*prev
) *prev
= (*prev
)->NextDevice
;
1016 NtClose( device
->Reserved
);
1017 HeapFree( GetProcessHeap(), 0, device
);
1022 /***********************************************************************
1023 * IoCreateSymbolicLink (NTOSKRNL.EXE.@)
1025 NTSTATUS WINAPI
IoCreateSymbolicLink( UNICODE_STRING
*name
, UNICODE_STRING
*target
)
1028 OBJECT_ATTRIBUTES attr
;
1030 attr
.Length
= sizeof(attr
);
1031 attr
.RootDirectory
= 0;
1032 attr
.ObjectName
= name
;
1033 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
;
1034 attr
.SecurityDescriptor
= NULL
;
1035 attr
.SecurityQualityOfService
= NULL
;
1037 TRACE( "%s -> %s\n", debugstr_us(name
), debugstr_us(target
) );
1038 /* FIXME: store handle somewhere */
1039 return NtCreateSymbolicLinkObject( &handle
, SYMBOLIC_LINK_ALL_ACCESS
, &attr
, target
);
1043 /***********************************************************************
1044 * IoDeleteSymbolicLink (NTOSKRNL.EXE.@)
1046 NTSTATUS WINAPI
IoDeleteSymbolicLink( UNICODE_STRING
*name
)
1049 OBJECT_ATTRIBUTES attr
;
1052 attr
.Length
= sizeof(attr
);
1053 attr
.RootDirectory
= 0;
1054 attr
.ObjectName
= name
;
1055 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
1056 attr
.SecurityDescriptor
= NULL
;
1057 attr
.SecurityQualityOfService
= NULL
;
1059 if (!(status
= NtOpenSymbolicLinkObject( &handle
, 0, &attr
)))
1061 SERVER_START_REQ( unlink_object
)
1063 req
->handle
= wine_server_obj_handle( handle
);
1064 status
= wine_server_call( req
);
1073 /***********************************************************************
1074 * IoGetDeviceInterfaces (NTOSKRNL.EXE.@)
1076 NTSTATUS WINAPI
IoGetDeviceInterfaces( const GUID
*InterfaceClassGuid
,
1077 PDEVICE_OBJECT PhysicalDeviceObject
,
1078 ULONG Flags
, PWSTR
*SymbolicLinkList
)
1080 FIXME( "stub: %s %p %x %p\n", debugstr_guid(InterfaceClassGuid
),
1081 PhysicalDeviceObject
, Flags
, SymbolicLinkList
);
1082 return STATUS_NOT_IMPLEMENTED
;
1086 /***********************************************************************
1087 * IoGetDeviceObjectPointer (NTOSKRNL.EXE.@)
1089 NTSTATUS WINAPI
IoGetDeviceObjectPointer( UNICODE_STRING
*name
, ACCESS_MASK access
, PFILE_OBJECT
*file
, PDEVICE_OBJECT
*device
)
1091 static DEVICE_OBJECT stub_device
;
1092 static DRIVER_OBJECT stub_driver
;
1094 FIXME( "stub: %s %x %p %p\n", debugstr_us(name
), access
, file
, device
);
1096 stub_device
.StackSize
= 0x80; /* minimum value to appease SecuROM 5.x */
1097 stub_device
.DriverObject
= &stub_driver
;
1100 *device
= &stub_device
;
1102 return STATUS_SUCCESS
;
1105 /***********************************************************************
1106 * IoGetAttachedDevice (NTOSKRNL.EXE.@)
1108 DEVICE_OBJECT
* WINAPI
IoGetAttachedDevice( DEVICE_OBJECT
*device
)
1110 DEVICE_OBJECT
*result
= device
;
1112 TRACE( "(%p)\n", device
);
1114 while (result
->AttachedDevice
)
1115 result
= result
->AttachedDevice
;
1121 /***********************************************************************
1122 * IoGetDeviceProperty (NTOSKRNL.EXE.@)
1124 NTSTATUS WINAPI
IoGetDeviceProperty( DEVICE_OBJECT
*device
, DEVICE_REGISTRY_PROPERTY device_property
,
1125 ULONG buffer_length
, PVOID property_buffer
, PULONG result_length
)
1127 NTSTATUS status
= STATUS_NOT_IMPLEMENTED
;
1128 TRACE( "%p %d %u %p %p\n", device
, device_property
, buffer_length
,
1129 property_buffer
, result_length
);
1130 switch (device_property
)
1132 case DevicePropertyPhysicalDeviceObjectName
:
1134 ULONG used_len
, len
= buffer_length
+ sizeof(OBJECT_NAME_INFORMATION
);
1135 OBJECT_NAME_INFORMATION
*name
= HeapAlloc(GetProcessHeap(), 0, len
);
1137 status
= NtQueryObject(device
->Reserved
, ObjectNameInformation
, name
, len
, &used_len
);
1138 if (status
== STATUS_SUCCESS
)
1140 /* Ensure room for NULL termination */
1141 if (buffer_length
>= name
->Name
.MaximumLength
)
1142 memcpy(property_buffer
, name
->Name
.Buffer
, name
->Name
.MaximumLength
);
1144 status
= STATUS_BUFFER_TOO_SMALL
;
1145 *result_length
= name
->Name
.MaximumLength
;
1149 if (status
== STATUS_INFO_LENGTH_MISMATCH
||
1150 status
== STATUS_BUFFER_OVERFLOW
)
1152 status
= STATUS_BUFFER_TOO_SMALL
;
1153 *result_length
= used_len
- sizeof(OBJECT_NAME_INFORMATION
);
1158 HeapFree(GetProcessHeap(), 0, name
);
1162 FIXME("unhandled property %d\n", device_property
);
1168 /***********************************************************************
1169 * IoCallDriver (NTOSKRNL.EXE.@)
1171 NTSTATUS WINAPI
IoCallDriver( DEVICE_OBJECT
*device
, IRP
*irp
)
1173 PDRIVER_DISPATCH dispatch
;
1174 IO_STACK_LOCATION
*irpsp
;
1177 --irp
->CurrentLocation
;
1178 irpsp
= --irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
;
1179 dispatch
= device
->DriverObject
->MajorFunction
[irpsp
->MajorFunction
];
1181 if (TRACE_ON(relay
))
1182 DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
1183 GetCurrentThreadId(), dispatch
, device
, irp
);
1185 status
= dispatch( device
, irp
);
1187 if (TRACE_ON(relay
))
1188 DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
1189 GetCurrentThreadId(), dispatch
, device
, irp
, status
);
1195 /***********************************************************************
1196 * IofCallDriver (NTOSKRNL.EXE.@)
1198 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1199 DEFINE_FASTCALL2_ENTRYPOINT( IofCallDriver
)
1200 NTSTATUS WINAPI
__regs_IofCallDriver( DEVICE_OBJECT
*device
, IRP
*irp
)
1202 NTSTATUS WINAPI
IofCallDriver( DEVICE_OBJECT
*device
, IRP
*irp
)
1205 TRACE( "%p %p\n", device
, irp
);
1206 return IoCallDriver( device
, irp
);
1210 /***********************************************************************
1211 * IoGetRelatedDeviceObject (NTOSKRNL.EXE.@)
1213 PDEVICE_OBJECT WINAPI
IoGetRelatedDeviceObject( PFILE_OBJECT obj
)
1215 FIXME( "stub: %p\n", obj
);
1219 static CONFIGURATION_INFORMATION configuration_information
;
1221 /***********************************************************************
1222 * IoGetConfigurationInformation (NTOSKRNL.EXE.@)
1224 PCONFIGURATION_INFORMATION WINAPI
IoGetConfigurationInformation(void)
1226 FIXME( "partial stub\n" );
1227 /* FIXME: return actual devices on system */
1228 return &configuration_information
;
1232 /***********************************************************************
1233 * IoIsWdmVersionAvailable (NTOSKRNL.EXE.@)
1235 NTSTATUS WINAPI
IoIsWdmVersionAvailable(UCHAR MajorVersion
, UCHAR MinorVersion
)
1241 TRACE( "%d, 0x%X\n", MajorVersion
, MinorVersion
);
1243 version
= GetVersion();
1244 major
= LOBYTE(version
);
1245 minor
= HIBYTE(LOWORD(version
));
1247 if (MajorVersion
== 6 && MinorVersion
== 0)
1249 /* Windows Vista, Windows Server 2008, Windows 7 */
1251 else if (MajorVersion
== 1)
1253 if (MinorVersion
== 0x30)
1255 /* Windows server 2003 */
1259 else if (MinorVersion
== 0x20)
1265 else if (MinorVersion
== 0x10)
1271 else if (MinorVersion
== 0x05)
1275 MinorVersion
= 0x5a;
1277 else if (MinorVersion
== 0x00)
1281 MinorVersion
= 0x0a;
1285 FIXME( "unknown major %d minor 0x%X\n", MajorVersion
, MinorVersion
);
1291 FIXME( "unknown major %d minor 0x%X\n", MajorVersion
, MinorVersion
);
1294 return major
> MajorVersion
|| (major
== MajorVersion
&& minor
>= MinorVersion
);
1298 /***********************************************************************
1299 * IoQueryDeviceDescription (NTOSKRNL.EXE.@)
1301 NTSTATUS WINAPI
IoQueryDeviceDescription(PINTERFACE_TYPE itype
, PULONG bus
, PCONFIGURATION_TYPE ctype
,
1302 PULONG cnum
, PCONFIGURATION_TYPE ptype
, PULONG pnum
,
1303 PIO_QUERY_DEVICE_ROUTINE callout
, PVOID context
)
1305 FIXME( "(%p %p %p %p %p %p %p %p)\n", itype
, bus
, ctype
, cnum
, ptype
, pnum
, callout
, context
);
1306 return STATUS_NOT_IMPLEMENTED
;
1310 /***********************************************************************
1311 * IoRegisterDriverReinitialization (NTOSKRNL.EXE.@)
1313 void WINAPI
IoRegisterDriverReinitialization( PDRIVER_OBJECT obj
, PDRIVER_REINITIALIZE reinit
, PVOID context
)
1315 FIXME( "stub: %p %p %p\n", obj
, reinit
, context
);
1319 /***********************************************************************
1320 * IoRegisterShutdownNotification (NTOSKRNL.EXE.@)
1322 NTSTATUS WINAPI
IoRegisterShutdownNotification( PDEVICE_OBJECT obj
)
1324 FIXME( "stub: %p\n", obj
);
1325 return STATUS_SUCCESS
;
1329 /***********************************************************************
1330 * IoUnregisterShutdownNotification (NTOSKRNL.EXE.@)
1332 VOID WINAPI
IoUnregisterShutdownNotification( PDEVICE_OBJECT obj
)
1334 FIXME( "stub: %p\n", obj
);
1338 /***********************************************************************
1339 * IoReportResourceUsage (NTOSKRNL.EXE.@)
1341 NTSTATUS WINAPI
IoReportResourceUsage(PUNICODE_STRING name
, PDRIVER_OBJECT drv_obj
, PCM_RESOURCE_LIST drv_list
,
1342 ULONG drv_size
, PDRIVER_OBJECT dev_obj
, PCM_RESOURCE_LIST dev_list
,
1343 ULONG dev_size
, BOOLEAN overwrite
, PBOOLEAN detected
)
1345 FIXME( "(%s, %p, %p, %u, %p, %p, %u, %d, %p): stub\n", debugstr_us(name
),
1346 drv_obj
, drv_list
, drv_size
, dev_obj
, dev_list
, dev_size
, overwrite
, detected
);
1347 return STATUS_NOT_IMPLEMENTED
;
1351 /***********************************************************************
1352 * IoCompleteRequest (NTOSKRNL.EXE.@)
1354 VOID WINAPI
IoCompleteRequest( IRP
*irp
, UCHAR priority_boost
)
1356 IO_STACK_LOCATION
*irpsp
;
1357 PIO_COMPLETION_ROUTINE routine
;
1358 NTSTATUS status
, stat
;
1362 TRACE( "%p %u\n", irp
, priority_boost
);
1364 status
= irp
->IoStatus
.u
.Status
;
1365 while (irp
->CurrentLocation
<= irp
->StackCount
)
1367 irpsp
= irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
;
1368 routine
= irpsp
->CompletionRoutine
;
1370 /* FIXME: add SL_INVOKE_ON_CANCEL support */
1373 if ((irpsp
->Control
& SL_INVOKE_ON_SUCCESS
) && STATUS_SUCCESS
== status
)
1375 if ((irpsp
->Control
& SL_INVOKE_ON_ERROR
) && STATUS_SUCCESS
!= status
)
1378 ++irp
->CurrentLocation
;
1379 ++irp
->Tail
.Overlay
.s
.u2
.CurrentStackLocation
;
1382 TRACE( "calling %p( %p, %p, %p )\n", routine
,
1383 irpsp
->DeviceObject
, irp
, irpsp
->Context
);
1384 stat
= routine( irpsp
->DeviceObject
, irp
, irpsp
->Context
);
1385 TRACE( "CompletionRoutine returned %x\n", stat
);
1386 if (STATUS_MORE_PROCESSING_REQUIRED
== stat
)
1391 handle
= (HANDLE
)irp
->UserIosb
;
1394 void *out_buff
= irp
->UserBuffer
;
1395 FILE_OBJECT
*file
= irp
->Tail
.Overlay
.OriginalFileObject
;
1397 SERVER_START_REQ( set_irp_result
)
1399 req
->handle
= wine_server_obj_handle( handle
);
1400 req
->status
= irp
->IoStatus
.u
.Status
;
1401 req
->file_ptr
= wine_server_client_ptr( file
);
1402 if (irp
->IoStatus
.u
.Status
>= 0)
1404 req
->size
= irp
->IoStatus
.Information
;
1405 if (out_buff
) wine_server_add_data( req
, out_buff
, irp
->IoStatus
.Information
);
1407 wine_server_call( req
);
1410 HeapFree( GetProcessHeap(), 0, out_buff
);
1417 /***********************************************************************
1418 * IofCompleteRequest (NTOSKRNL.EXE.@)
1420 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1421 DEFINE_FASTCALL2_ENTRYPOINT( IofCompleteRequest
)
1422 void WINAPI
__regs_IofCompleteRequest( IRP
*irp
, UCHAR priority_boost
)
1424 void WINAPI
IofCompleteRequest( IRP
*irp
, UCHAR priority_boost
)
1427 TRACE( "%p %u\n", irp
, priority_boost
);
1428 IoCompleteRequest( irp
, priority_boost
);
1432 /***********************************************************************
1433 * InterlockedCompareExchange (NTOSKRNL.EXE.@)
1435 #ifdef DEFINE_FASTCALL3_ENTRYPOINT
1436 DEFINE_FASTCALL3_ENTRYPOINT( NTOSKRNL_InterlockedCompareExchange
)
1437 LONG WINAPI
__regs_NTOSKRNL_InterlockedCompareExchange( LONG
volatile *dest
, LONG xchg
, LONG compare
)
1439 LONG WINAPI
NTOSKRNL_InterlockedCompareExchange( LONG
volatile *dest
, LONG xchg
, LONG compare
)
1442 return InterlockedCompareExchange( dest
, xchg
, compare
);
1446 /***********************************************************************
1447 * InterlockedDecrement (NTOSKRNL.EXE.@)
1449 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1450 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedDecrement
)
1451 LONG WINAPI
__regs_NTOSKRNL_InterlockedDecrement( LONG
volatile *dest
)
1453 LONG WINAPI
NTOSKRNL_InterlockedDecrement( LONG
volatile *dest
)
1456 return InterlockedDecrement( dest
);
1460 /***********************************************************************
1461 * InterlockedExchange (NTOSKRNL.EXE.@)
1463 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1464 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchange
)
1465 LONG WINAPI
__regs_NTOSKRNL_InterlockedExchange( LONG
volatile *dest
, LONG val
)
1467 LONG WINAPI
NTOSKRNL_InterlockedExchange( LONG
volatile *dest
, LONG val
)
1470 return InterlockedExchange( dest
, val
);
1474 /***********************************************************************
1475 * InterlockedExchangeAdd (NTOSKRNL.EXE.@)
1477 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1478 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchangeAdd
)
1479 LONG WINAPI
__regs_NTOSKRNL_InterlockedExchangeAdd( LONG
volatile *dest
, LONG incr
)
1481 LONG WINAPI
NTOSKRNL_InterlockedExchangeAdd( LONG
volatile *dest
, LONG incr
)
1484 return InterlockedExchangeAdd( dest
, incr
);
1488 /***********************************************************************
1489 * InterlockedIncrement (NTOSKRNL.EXE.@)
1491 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1492 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedIncrement
)
1493 LONG WINAPI
__regs_NTOSKRNL_InterlockedIncrement( LONG
volatile *dest
)
1495 LONG WINAPI
NTOSKRNL_InterlockedIncrement( LONG
volatile *dest
)
1498 return InterlockedIncrement( dest
);
1502 /***********************************************************************
1503 * InterlockedPopEntrySList (NTOSKRNL.EXE.@)
1505 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
1506 DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedPopEntrySList
)
1507 PSLIST_ENTRY WINAPI
__regs_NTOSKRNL_InterlockedPopEntrySList( PSLIST_HEADER list
)
1509 PSLIST_ENTRY WINAPI
NTOSKRNL_InterlockedPopEntrySList( PSLIST_HEADER list
)
1512 return InterlockedPopEntrySList( list
);
1516 /***********************************************************************
1517 * InterlockedPushEntrySList (NTOSKRNL.EXE.@)
1519 #ifdef DEFINE_FASTCALL2_ENTRYPOINT
1520 DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedPushEntrySList
)
1521 PSLIST_ENTRY WINAPI
__regs_NTOSKRNL_InterlockedPushEntrySList( PSLIST_HEADER list
, PSLIST_ENTRY entry
)
1523 PSLIST_ENTRY WINAPI
NTOSKRNL_InterlockedPushEntrySList( PSLIST_HEADER list
, PSLIST_ENTRY entry
)
1526 return InterlockedPushEntrySList( list
, entry
);
1530 /***********************************************************************
1531 * ExAllocatePool (NTOSKRNL.EXE.@)
1533 PVOID WINAPI
ExAllocatePool( POOL_TYPE type
, SIZE_T size
)
1535 return ExAllocatePoolWithTag( type
, size
, 0 );
1539 /***********************************************************************
1540 * ExAllocatePoolWithQuota (NTOSKRNL.EXE.@)
1542 PVOID WINAPI
ExAllocatePoolWithQuota( POOL_TYPE type
, SIZE_T size
)
1544 return ExAllocatePoolWithTag( type
, size
, 0 );
1548 /***********************************************************************
1549 * ExAllocatePoolWithTag (NTOSKRNL.EXE.@)
1551 PVOID WINAPI
ExAllocatePoolWithTag( POOL_TYPE type
, SIZE_T size
, ULONG tag
)
1553 /* FIXME: handle page alignment constraints */
1554 void *ret
= HeapAlloc( GetProcessHeap(), 0, size
);
1555 TRACE( "%lu pool %u -> %p\n", size
, type
, ret
);
1560 /***********************************************************************
1561 * ExAllocatePoolWithQuotaTag (NTOSKRNL.EXE.@)
1563 PVOID WINAPI
ExAllocatePoolWithQuotaTag( POOL_TYPE type
, SIZE_T size
, ULONG tag
)
1565 return ExAllocatePoolWithTag( type
, size
, tag
);
1569 /***********************************************************************
1570 * ExCreateCallback (NTOSKRNL.EXE.@)
1572 NTSTATUS WINAPI
ExCreateCallback(PCALLBACK_OBJECT
*obj
, POBJECT_ATTRIBUTES attr
,
1573 BOOLEAN create
, BOOLEAN allow_multiple
)
1575 FIXME("(%p, %p, %u, %u): stub\n", obj
, attr
, create
, allow_multiple
);
1577 return STATUS_NOT_IMPLEMENTED
;
1581 /***********************************************************************
1582 * ExDeleteNPagedLookasideList (NTOSKRNL.EXE.@)
1584 void WINAPI
ExDeleteNPagedLookasideList( PNPAGED_LOOKASIDE_LIST lookaside
)
1586 FIXME("(%p) stub\n", lookaside
);
1590 /***********************************************************************
1591 * ExDeletePagedLookasideList (NTOSKRNL.EXE.@)
1593 void WINAPI
ExDeletePagedLookasideList( PPAGED_LOOKASIDE_LIST lookaside
)
1595 FIXME("(%p) stub\n", lookaside
);
1599 /***********************************************************************
1600 * ExFreePool (NTOSKRNL.EXE.@)
1602 void WINAPI
ExFreePool( void *ptr
)
1604 ExFreePoolWithTag( ptr
, 0 );
1608 /***********************************************************************
1609 * ExFreePoolWithTag (NTOSKRNL.EXE.@)
1611 void WINAPI
ExFreePoolWithTag( void *ptr
, ULONG tag
)
1613 TRACE( "%p\n", ptr
);
1614 HeapFree( GetProcessHeap(), 0, ptr
);
1618 /***********************************************************************
1619 * ExInitializeResourceLite (NTOSKRNL.EXE.@)
1621 NTSTATUS WINAPI
ExInitializeResourceLite(PERESOURCE Resource
)
1623 FIXME( "stub: %p\n", Resource
);
1624 return STATUS_NOT_IMPLEMENTED
;
1628 /***********************************************************************
1629 * ExInitializeNPagedLookasideList (NTOSKRNL.EXE.@)
1631 void WINAPI
ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside
,
1632 PALLOCATE_FUNCTION Allocate
,
1633 PFREE_FUNCTION Free
,
1639 FIXME( "stub: %p, %p, %p, %u, %lu, %u, %u\n", Lookaside
, Allocate
, Free
, Flags
, Size
, Tag
, Depth
);
1642 /***********************************************************************
1643 * ExInitializePagedLookasideList (NTOSKRNL.EXE.@)
1645 void WINAPI
ExInitializePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside
,
1646 PALLOCATE_FUNCTION Allocate
,
1647 PFREE_FUNCTION Free
,
1653 FIXME( "stub: %p, %p, %p, %u, %lu, %u, %u\n", Lookaside
, Allocate
, Free
, Flags
, Size
, Tag
, Depth
);
1656 /***********************************************************************
1657 * ExInitializeZone (NTOSKRNL.EXE.@)
1659 NTSTATUS WINAPI
ExInitializeZone(PZONE_HEADER Zone
,
1661 PVOID InitialSegment
,
1662 ULONG InitialSegmentSize
)
1664 FIXME( "stub: %p, %u, %p, %u\n", Zone
, BlockSize
, InitialSegment
, InitialSegmentSize
);
1665 return STATUS_NOT_IMPLEMENTED
;
1668 /***********************************************************************
1669 * FsRtlRegisterUncProvider (NTOSKRNL.EXE.@)
1671 NTSTATUS WINAPI
FsRtlRegisterUncProvider(PHANDLE MupHandle
, PUNICODE_STRING RedirDevName
,
1672 BOOLEAN MailslotsSupported
)
1674 FIXME("(%p %p %d): stub\n", MupHandle
, RedirDevName
, MailslotsSupported
);
1675 return STATUS_NOT_IMPLEMENTED
;
1678 /***********************************************************************
1679 * IoGetCurrentProcess / PsGetCurrentProcess (NTOSKRNL.EXE.@)
1681 PEPROCESS WINAPI
IoGetCurrentProcess(void)
1687 /***********************************************************************
1688 * KeGetCurrentThread / PsGetCurrentThread (NTOSKRNL.EXE.@)
1690 PRKTHREAD WINAPI
KeGetCurrentThread(void)
1696 /***********************************************************************
1697 * KeInitializeEvent (NTOSKRNL.EXE.@)
1699 void WINAPI
KeInitializeEvent( PRKEVENT Event
, EVENT_TYPE Type
, BOOLEAN State
)
1701 FIXME( "stub: %p %d %d\n", Event
, Type
, State
);
1705 /***********************************************************************
1706 * KeInitializeMutex (NTOSKRNL.EXE.@)
1708 void WINAPI
KeInitializeMutex(PRKMUTEX Mutex
, ULONG Level
)
1710 FIXME( "stub: %p, %u\n", Mutex
, Level
);
1714 /***********************************************************************
1715 * KeWaitForMutexObject (NTOSKRNL.EXE.@)
1717 NTSTATUS WINAPI
KeWaitForMutexObject(PRKMUTEX Mutex
, KWAIT_REASON WaitReason
, KPROCESSOR_MODE WaitMode
,
1718 BOOLEAN Alertable
, PLARGE_INTEGER Timeout
)
1720 FIXME( "stub: %p, %d, %d, %d, %p\n", Mutex
, WaitReason
, WaitMode
, Alertable
, Timeout
);
1721 return STATUS_NOT_IMPLEMENTED
;
1725 /***********************************************************************
1726 * KeReleaseMutex (NTOSKRNL.EXE.@)
1728 LONG WINAPI
KeReleaseMutex(PRKMUTEX Mutex
, BOOLEAN Wait
)
1730 FIXME( "stub: %p, %d\n", Mutex
, Wait
);
1731 return STATUS_NOT_IMPLEMENTED
;
1735 /***********************************************************************
1736 * KeInitializeSemaphore (NTOSKRNL.EXE.@)
1738 void WINAPI
KeInitializeSemaphore( PRKSEMAPHORE Semaphore
, LONG Count
, LONG Limit
)
1740 FIXME( "(%p %d %d) stub\n", Semaphore
, Count
, Limit
);
1744 /***********************************************************************
1745 * KeInitializeSpinLock (NTOSKRNL.EXE.@)
1747 void WINAPI
KeInitializeSpinLock( PKSPIN_LOCK SpinLock
)
1749 FIXME( "stub: %p\n", SpinLock
);
1753 /***********************************************************************
1754 * KeInitializeTimerEx (NTOSKRNL.EXE.@)
1756 void WINAPI
KeInitializeTimerEx( PKTIMER Timer
, TIMER_TYPE Type
)
1758 FIXME( "stub: %p %d\n", Timer
, Type
);
1762 /***********************************************************************
1763 * KeInitializeTimer (NTOSKRNL.EXE.@)
1765 void WINAPI
KeInitializeTimer( PKTIMER Timer
)
1767 KeInitializeTimerEx(Timer
, NotificationTimer
);
1770 /***********************************************************************
1771 * KeInsertQueue (NTOSKRNL.EXE.@)
1773 LONG WINAPI
KeInsertQueue(PRKQUEUE Queue
, PLIST_ENTRY Entry
)
1775 FIXME( "stub: %p %p\n", Queue
, Entry
);
1779 /**********************************************************************
1780 * KeQueryActiveProcessors (NTOSKRNL.EXE.@)
1782 * Return the active Processors as bitmask
1785 * active Processors as bitmask
1788 KAFFINITY WINAPI
KeQueryActiveProcessors( void )
1790 DWORD_PTR AffinityMask
;
1792 GetProcessAffinityMask( GetCurrentProcess(), &AffinityMask
, NULL
);
1793 return AffinityMask
;
1797 /**********************************************************************
1798 * KeQueryInterruptTime (NTOSKRNL.EXE.@)
1800 * Return the interrupt time count
1803 ULONGLONG WINAPI
KeQueryInterruptTime( void )
1805 LARGE_INTEGER totaltime
;
1807 KeQueryTickCount(&totaltime
);
1808 return totaltime
.QuadPart
;
1812 /***********************************************************************
1813 * KeQuerySystemTime (NTOSKRNL.EXE.@)
1815 void WINAPI
KeQuerySystemTime( LARGE_INTEGER
*time
)
1817 NtQuerySystemTime( time
);
1821 /***********************************************************************
1822 * KeQueryTickCount (NTOSKRNL.EXE.@)
1824 void WINAPI
KeQueryTickCount( LARGE_INTEGER
*count
)
1826 count
->QuadPart
= NtGetTickCount();
1827 /* update the global variable too */
1828 KeTickCount
.LowPart
= count
->u
.LowPart
;
1829 KeTickCount
.High1Time
= count
->u
.HighPart
;
1830 KeTickCount
.High2Time
= count
->u
.HighPart
;
1834 /***********************************************************************
1835 * KeReleaseSemaphore (NTOSKRNL.EXE.@)
1837 LONG WINAPI
KeReleaseSemaphore( PRKSEMAPHORE Semaphore
, KPRIORITY Increment
,
1838 LONG Adjustment
, BOOLEAN Wait
)
1840 FIXME("(%p %d %d %d) stub\n", Semaphore
, Increment
, Adjustment
, Wait
);
1845 /***********************************************************************
1846 * KeQueryTimeIncrement (NTOSKRNL.EXE.@)
1848 ULONG WINAPI
KeQueryTimeIncrement(void)
1854 /***********************************************************************
1855 * KeResetEvent (NTOSKRNL.EXE.@)
1857 LONG WINAPI
KeResetEvent( PRKEVENT Event
)
1859 FIXME("(%p): stub\n", Event
);
1864 /***********************************************************************
1865 * KeSetEvent (NTOSKRNL.EXE.@)
1867 LONG WINAPI
KeSetEvent( PRKEVENT Event
, KPRIORITY Increment
, BOOLEAN Wait
)
1869 FIXME("(%p, %d, %d): stub\n", Event
, Increment
, Wait
);
1874 /***********************************************************************
1875 * KeSetPriorityThread (NTOSKRNL.EXE.@)
1877 KPRIORITY WINAPI
KeSetPriorityThread( PKTHREAD Thread
, KPRIORITY Priority
)
1879 FIXME("(%p %d)\n", Thread
, Priority
);
1883 /***********************************************************************
1884 * KeSetSystemAffinityThread (NTOSKRNL.EXE.@)
1886 VOID WINAPI
KeSetSystemAffinityThread(KAFFINITY Affinity
)
1888 FIXME("(%lx) stub\n", Affinity
);
1891 /***********************************************************************
1892 * KeWaitForSingleObject (NTOSKRNL.EXE.@)
1894 NTSTATUS WINAPI
KeWaitForSingleObject(PVOID Object
,
1895 KWAIT_REASON WaitReason
,
1896 KPROCESSOR_MODE WaitMode
,
1898 PLARGE_INTEGER Timeout
)
1900 FIXME( "stub: %p, %d, %d, %d, %p\n", Object
, WaitReason
, WaitMode
, Alertable
, Timeout
);
1901 return STATUS_NOT_IMPLEMENTED
;
1904 /***********************************************************************
1905 * IoRegisterFileSystem (NTOSKRNL.EXE.@)
1907 VOID WINAPI
IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject
)
1909 FIXME("(%p): stub\n", DeviceObject
);
1912 /***********************************************************************
1913 * IoUnregisterFileSystem (NTOSKRNL.EXE.@)
1915 VOID WINAPI
IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject
)
1917 FIXME("(%p): stub\n", DeviceObject
);
1920 /***********************************************************************
1921 * MmAllocateNonCachedMemory (NTOSKRNL.EXE.@)
1923 PVOID WINAPI
MmAllocateNonCachedMemory( SIZE_T size
)
1925 TRACE( "%lu\n", size
);
1926 return VirtualAlloc( NULL
, size
, MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
|PAGE_NOCACHE
);
1929 /***********************************************************************
1930 * MmAllocateContiguousMemory (NTOSKRNL.EXE.@)
1932 PVOID WINAPI
MmAllocateContiguousMemory( SIZE_T size
, PHYSICAL_ADDRESS highest_valid_address
)
1934 FIXME( "%lu, %s stub\n", size
, wine_dbgstr_longlong(highest_valid_address
.QuadPart
) );
1938 /***********************************************************************
1939 * MmAllocateContiguousMemorySpecifyCache (NTOSKRNL.EXE.@)
1941 PVOID WINAPI
MmAllocateContiguousMemorySpecifyCache( SIZE_T size
,
1942 PHYSICAL_ADDRESS lowest_valid_address
,
1943 PHYSICAL_ADDRESS highest_valid_address
,
1944 PHYSICAL_ADDRESS BoundaryAddressMultiple
,
1945 MEMORY_CACHING_TYPE CacheType
)
1951 /***********************************************************************
1952 * MmAllocatePagesForMdl (NTOSKRNL.EXE.@)
1954 PMDL WINAPI
MmAllocatePagesForMdl(PHYSICAL_ADDRESS lowaddress
, PHYSICAL_ADDRESS highaddress
,
1955 PHYSICAL_ADDRESS skipbytes
, SIZE_T size
)
1957 FIXME("%s %s %s %lu: stub\n", wine_dbgstr_longlong(lowaddress
.QuadPart
), wine_dbgstr_longlong(highaddress
.QuadPart
),
1958 wine_dbgstr_longlong(skipbytes
.QuadPart
), size
);
1962 /***********************************************************************
1963 * MmFreeNonCachedMemory (NTOSKRNL.EXE.@)
1965 void WINAPI
MmFreeNonCachedMemory( void *addr
, SIZE_T size
)
1967 TRACE( "%p %lu\n", addr
, size
);
1968 VirtualFree( addr
, 0, MEM_RELEASE
);
1971 /***********************************************************************
1972 * MmIsAddressValid (NTOSKRNL.EXE.@)
1974 * Check if the process can access the virtual address without a pagefault
1977 * VirtualAddress [I] Address to check
1981 * Success: TRUE (Accessing the Address works without a Pagefault)
1984 BOOLEAN WINAPI
MmIsAddressValid(PVOID VirtualAddress
)
1986 TRACE("(%p)\n", VirtualAddress
);
1987 return !IsBadWritePtr(VirtualAddress
, 1);
1990 /***********************************************************************
1991 * MmMapIoSpace (NTOSKRNL.EXE.@)
1993 PVOID WINAPI
MmMapIoSpace( PHYSICAL_ADDRESS PhysicalAddress
, DWORD NumberOfBytes
, DWORD CacheType
)
1995 FIXME( "stub: 0x%08x%08x, %d, %d\n", PhysicalAddress
.u
.HighPart
, PhysicalAddress
.u
.LowPart
, NumberOfBytes
, CacheType
);
2000 /***********************************************************************
2001 * MmLockPagableSectionByHandle (NTOSKRNL.EXE.@)
2003 VOID WINAPI
MmLockPagableSectionByHandle(PVOID ImageSectionHandle
)
2005 FIXME("stub %p\n", ImageSectionHandle
);
2008 /***********************************************************************
2009 * MmMapLockedPagesSpecifyCache (NTOSKRNL.EXE.@)
2011 PVOID WINAPI
MmMapLockedPagesSpecifyCache(PMDLX MemoryDescriptorList
, KPROCESSOR_MODE AccessMode
, MEMORY_CACHING_TYPE CacheType
,
2012 PVOID BaseAddress
, ULONG BugCheckOnFailure
, MM_PAGE_PRIORITY Priority
)
2014 FIXME("(%p, %u, %u, %p, %u, %u): stub\n", MemoryDescriptorList
, AccessMode
, CacheType
, BaseAddress
, BugCheckOnFailure
, Priority
);
2019 /***********************************************************************
2020 * MmUnlockPagableImageSection (NTOSKRNL.EXE.@)
2022 VOID WINAPI
MmUnlockPagableImageSection(PVOID ImageSectionHandle
)
2024 FIXME("stub %p\n", ImageSectionHandle
);
2027 /***********************************************************************
2028 * MmPageEntireDriver (NTOSKRNL.EXE.@)
2030 PVOID WINAPI
MmPageEntireDriver(PVOID AddrInSection
)
2032 TRACE("%p\n", AddrInSection
);
2033 return AddrInSection
;
2037 /***********************************************************************
2038 * MmProbeAndLockPages (NTOSKRNL.EXE.@)
2040 void WINAPI
MmProbeAndLockPages(PMDLX MemoryDescriptorList
, KPROCESSOR_MODE AccessMode
, LOCK_OPERATION Operation
)
2042 FIXME("(%p, %u, %u): stub\n", MemoryDescriptorList
, AccessMode
, Operation
);
2046 /***********************************************************************
2047 * MmResetDriverPaging (NTOSKRNL.EXE.@)
2049 void WINAPI
MmResetDriverPaging(PVOID AddrInSection
)
2051 TRACE("%p\n", AddrInSection
);
2055 /***********************************************************************
2056 * MmUnlockPages (NTOSKRNL.EXE.@)
2058 void WINAPI
MmUnlockPages(PMDLX MemoryDescriptorList
)
2060 FIXME("(%p): stub\n", MemoryDescriptorList
);
2064 /***********************************************************************
2065 * MmUnmapIoSpace (NTOSKRNL.EXE.@)
2067 VOID WINAPI
MmUnmapIoSpace( PVOID BaseAddress
, SIZE_T NumberOfBytes
)
2069 FIXME( "stub: %p, %lu\n", BaseAddress
, NumberOfBytes
);
2073 /***********************************************************************
2074 * ObReferenceObjectByHandle (NTOSKRNL.EXE.@)
2076 NTSTATUS WINAPI
ObReferenceObjectByHandle( HANDLE obj
, ACCESS_MASK access
,
2078 KPROCESSOR_MODE mode
, PVOID
* ptr
,
2079 POBJECT_HANDLE_INFORMATION info
)
2081 FIXME( "stub: %p %x %p %d %p %p\n", obj
, access
, type
, mode
, ptr
, info
);
2082 return STATUS_NOT_IMPLEMENTED
;
2085 /***********************************************************************
2086 * ObReferenceObjectByName (NTOSKRNL.EXE.@)
2088 NTSTATUS WINAPI
ObReferenceObjectByName( UNICODE_STRING
*ObjectName
,
2090 ACCESS_STATE
*AccessState
,
2091 ACCESS_MASK DesiredAccess
,
2092 POBJECT_TYPE ObjectType
,
2093 KPROCESSOR_MODE AccessMode
,
2097 struct wine_driver
*driver
;
2098 struct wine_rb_entry
*entry
;
2100 TRACE("mostly-stub:%s %i %p %i %p %i %p %p\n", debugstr_us(ObjectName
),
2101 Attributes
, AccessState
, DesiredAccess
, ObjectType
, AccessMode
,
2102 ParseContext
, Object
);
2104 if (AccessState
) FIXME("Unhandled AccessState\n");
2105 if (DesiredAccess
) FIXME("Unhandled DesiredAccess\n");
2106 if (ParseContext
) FIXME("Unhandled ParseContext\n");
2107 if (ObjectType
) FIXME("Unhandled ObjectType\n");
2109 if (AccessMode
!= KernelMode
)
2111 FIXME("UserMode access not implemented\n");
2112 return STATUS_NOT_IMPLEMENTED
;
2115 EnterCriticalSection(&drivers_cs
);
2116 entry
= wine_rb_get(&wine_drivers
, ObjectName
);
2117 LeaveCriticalSection(&drivers_cs
);
2120 FIXME("Object (%s) not found, may not be tracked.\n", debugstr_us(ObjectName
));
2121 return STATUS_NOT_IMPLEMENTED
;
2124 driver
= WINE_RB_ENTRY_VALUE(entry
, struct wine_driver
, entry
);
2125 *Object
= &driver
->driver_obj
;
2126 return STATUS_SUCCESS
;
2130 static void ObReferenceObject( void *obj
)
2132 TRACE( "(%p): stub\n", obj
);
2136 /***********************************************************************
2137 * ObDereferenceObject (NTOSKRNL.EXE.@)
2139 void WINAPI
ObDereferenceObject( void *obj
)
2141 TRACE( "(%p): stub\n", obj
);
2145 /***********************************************************************
2146 * ObfReferenceObject (NTOSKRNL.EXE.@)
2148 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
2149 DEFINE_FASTCALL1_ENTRYPOINT( ObfReferenceObject
)
2150 void WINAPI
__regs_ObfReferenceObject( void *obj
)
2152 void WINAPI
ObfReferenceObject( void *obj
)
2155 ObReferenceObject( obj
);
2159 /***********************************************************************
2160 * ObfDereferenceObject (NTOSKRNL.EXE.@)
2162 #ifdef DEFINE_FASTCALL1_ENTRYPOINT
2163 DEFINE_FASTCALL1_ENTRYPOINT( ObfDereferenceObject
)
2164 void WINAPI
__regs_ObfDereferenceObject( void *obj
)
2166 void WINAPI
ObfDereferenceObject( void *obj
)
2169 ObDereferenceObject( obj
);
2173 /***********************************************************************
2174 * IoGetAttachedDeviceReference (NTOSKRNL.EXE.@)
2176 DEVICE_OBJECT
* WINAPI
IoGetAttachedDeviceReference( DEVICE_OBJECT
*device
)
2178 DEVICE_OBJECT
*result
= IoGetAttachedDevice( device
);
2179 ObReferenceObject( result
);
2184 /***********************************************************************
2185 * PsCreateSystemThread (NTOSKRNL.EXE.@)
2187 NTSTATUS WINAPI
PsCreateSystemThread(PHANDLE ThreadHandle
, ULONG DesiredAccess
,
2188 POBJECT_ATTRIBUTES ObjectAttributes
,
2189 HANDLE ProcessHandle
, PCLIENT_ID ClientId
,
2190 PKSTART_ROUTINE StartRoutine
, PVOID StartContext
)
2192 if (!ProcessHandle
) ProcessHandle
= GetCurrentProcess();
2193 return RtlCreateUserThread(ProcessHandle
, 0, FALSE
, 0, 0,
2194 0, StartRoutine
, StartContext
,
2195 ThreadHandle
, ClientId
);
2198 /***********************************************************************
2199 * PsGetCurrentProcessId (NTOSKRNL.EXE.@)
2201 HANDLE WINAPI
PsGetCurrentProcessId(void)
2203 if (GetCurrentThreadId() == request_thread
)
2204 return UlongToHandle(client_pid
);
2205 return UlongToHandle(GetCurrentProcessId());
2209 /***********************************************************************
2210 * PsGetCurrentThreadId (NTOSKRNL.EXE.@)
2212 HANDLE WINAPI
PsGetCurrentThreadId(void)
2214 if (GetCurrentThreadId() == request_thread
)
2215 return UlongToHandle(client_tid
);
2216 return UlongToHandle(GetCurrentThreadId());
2220 /***********************************************************************
2221 * PsGetVersion (NTOSKRNL.EXE.@)
2223 BOOLEAN WINAPI
PsGetVersion(ULONG
*major
, ULONG
*minor
, ULONG
*build
, UNICODE_STRING
*version
)
2225 RTL_OSVERSIONINFOEXW info
;
2227 info
.dwOSVersionInfoSize
= sizeof(info
);
2228 RtlGetVersion( &info
);
2229 if (major
) *major
= info
.dwMajorVersion
;
2230 if (minor
) *minor
= info
.dwMinorVersion
;
2231 if (build
) *build
= info
.dwBuildNumber
;
2235 #if 0 /* FIXME: GameGuard passes an uninitialized pointer in version->Buffer */
2236 size_t len
= min( strlenW(info
.szCSDVersion
)*sizeof(WCHAR
), version
->MaximumLength
);
2237 memcpy( version
->Buffer
, info
.szCSDVersion
, len
);
2238 if (len
< version
->MaximumLength
) version
->Buffer
[len
/ sizeof(WCHAR
)] = 0;
2239 version
->Length
= len
;
2246 /***********************************************************************
2247 * PsImpersonateClient (NTOSKRNL.EXE.@)
2249 NTSTATUS WINAPI
PsImpersonateClient(PETHREAD Thread
, PACCESS_TOKEN Token
, BOOLEAN CopyOnOpen
,
2250 BOOLEAN EffectiveOnly
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
2252 FIXME("(%p, %p, %u, %u, %u): stub\n", Thread
, Token
, CopyOnOpen
, EffectiveOnly
, ImpersonationLevel
);
2254 return STATUS_NOT_IMPLEMENTED
;
2258 /***********************************************************************
2259 * PsSetCreateProcessNotifyRoutine (NTOSKRNL.EXE.@)
2261 NTSTATUS WINAPI
PsSetCreateProcessNotifyRoutine( PCREATE_PROCESS_NOTIFY_ROUTINE callback
, BOOLEAN remove
)
2263 FIXME( "stub: %p %d\n", callback
, remove
);
2264 return STATUS_SUCCESS
;
2268 /***********************************************************************
2269 * PsSetCreateThreadNotifyRoutine (NTOSKRNL.EXE.@)
2271 NTSTATUS WINAPI
PsSetCreateThreadNotifyRoutine( PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
)
2273 FIXME( "stub: %p\n", NotifyRoutine
);
2274 return STATUS_SUCCESS
;
2278 /***********************************************************************
2279 * PsRemoveCreateThreadNotifyRoutine (NTOSKRNL.EXE.@)
2281 NTSTATUS WINAPI
PsRemoveCreateThreadNotifyRoutine( PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
)
2283 FIXME( "stub: %p\n", NotifyRoutine
);
2284 return STATUS_SUCCESS
;
2288 /***********************************************************************
2289 * PsRemoveLoadImageNotifyRoutine (NTOSKRNL.EXE.@)
2291 NTSTATUS WINAPI
PsRemoveLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
)
2293 FIXME( "stub: %p\n", NotifyRoutine
);
2294 return STATUS_SUCCESS
;
2298 /***********************************************************************
2299 * PsTerminateSystemThread (NTOSKRNL.EXE.@)
2301 NTSTATUS WINAPI
PsTerminateSystemThread(NTSTATUS ExitStatus
)
2303 FIXME( "stub: %u\n", ExitStatus
);
2304 return STATUS_NOT_IMPLEMENTED
;
2308 /***********************************************************************
2309 * MmGetSystemRoutineAddress (NTOSKRNL.EXE.@)
2311 PVOID WINAPI
MmGetSystemRoutineAddress(PUNICODE_STRING SystemRoutineName
)
2314 STRING routineNameA
;
2317 static const WCHAR ntoskrnlW
[] = {'n','t','o','s','k','r','n','l','.','e','x','e',0};
2318 static const WCHAR halW
[] = {'h','a','l','.','d','l','l',0};
2320 if (!SystemRoutineName
) return NULL
;
2322 if (RtlUnicodeStringToAnsiString( &routineNameA
, SystemRoutineName
, TRUE
) == STATUS_SUCCESS
)
2324 /* We only support functions exported from ntoskrnl.exe or hal.dll */
2325 hMod
= GetModuleHandleW( ntoskrnlW
);
2326 pFunc
= GetProcAddress( hMod
, routineNameA
.Buffer
);
2329 hMod
= GetModuleHandleW( halW
);
2330 if (hMod
) pFunc
= GetProcAddress( hMod
, routineNameA
.Buffer
);
2332 RtlFreeAnsiString( &routineNameA
);
2336 TRACE( "%s -> %p\n", debugstr_us(SystemRoutineName
), pFunc
);
2338 FIXME( "%s not found\n", debugstr_us(SystemRoutineName
) );
2343 /***********************************************************************
2344 * MmQuerySystemSize (NTOSKRNL.EXE.@)
2346 MM_SYSTEMSIZE WINAPI
MmQuerySystemSize(void)
2349 return MmLargeSystem
;
2352 /***********************************************************************
2353 * KeInitializeDpc (NTOSKRNL.EXE.@)
2355 VOID WINAPI
KeInitializeDpc(PRKDPC Dpc
, PKDEFERRED_ROUTINE DeferredRoutine
, PVOID DeferredContext
)
2360 /***********************************************************************
2361 * READ_REGISTER_BUFFER_UCHAR (NTOSKRNL.EXE.@)
2363 VOID WINAPI
READ_REGISTER_BUFFER_UCHAR(PUCHAR Register
, PUCHAR Buffer
, ULONG Count
)
2368 /*****************************************************
2369 * PoSetPowerState (NTOSKRNL.EXE.@)
2371 POWER_STATE WINAPI
PoSetPowerState(PDEVICE_OBJECT DeviceObject
, POWER_STATE_TYPE Type
, POWER_STATE State
)
2373 FIXME("(%p %u %u) stub\n", DeviceObject
, Type
, State
.DeviceState
);
2377 /*****************************************************
2378 * IoWMIRegistrationControl (NTOSKRNL.EXE.@)
2380 NTSTATUS WINAPI
IoWMIRegistrationControl(PDEVICE_OBJECT DeviceObject
, ULONG Action
)
2382 FIXME("(%p %u) stub\n", DeviceObject
, Action
);
2383 return STATUS_SUCCESS
;
2386 /*****************************************************
2387 * PsSetLoadImageNotifyRoutine (NTOSKRNL.EXE.@)
2389 NTSTATUS WINAPI
PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine
)
2391 FIXME("(%p) stub\n", routine
);
2392 return STATUS_SUCCESS
;
2395 /*****************************************************
2396 * PsLookupProcessByProcessId (NTOSKRNL.EXE.@)
2398 NTSTATUS WINAPI
PsLookupProcessByProcessId(HANDLE processid
, PEPROCESS
*process
)
2401 if (!once
++) FIXME("(%p %p) stub\n", processid
, process
);
2402 return STATUS_NOT_IMPLEMENTED
;
2406 /*****************************************************
2407 * IoSetThreadHardErrorMode (NTOSKRNL.EXE.@)
2409 BOOLEAN WINAPI
IoSetThreadHardErrorMode(BOOLEAN EnableHardErrors
)
2416 /*****************************************************
2417 * IoInitializeRemoveLockEx (NTOSKRNL.EXE.@)
2419 VOID WINAPI
IoInitializeRemoveLockEx(PIO_REMOVE_LOCK lock
, ULONG tag
,
2420 ULONG maxmin
, ULONG high
, ULONG size
)
2422 FIXME("(%p %u %u %u %u) stub\n", lock
, tag
, maxmin
, high
, size
);
2426 /*****************************************************
2427 * IoAcquireRemoveLockEx (NTOSKRNL.EXE.@)
2430 NTSTATUS WINAPI
IoAcquireRemoveLockEx(PIO_REMOVE_LOCK lock
, PVOID tag
,
2431 LPCSTR file
, ULONG line
, ULONG lock_size
)
2433 FIXME("(%p, %p, %s, %u, %u): stub\n", lock
, tag
, debugstr_a(file
), line
, lock_size
);
2435 return STATUS_NOT_IMPLEMENTED
;
2439 /*****************************************************
2442 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
2444 static void *handler
;
2445 LARGE_INTEGER count
;
2449 case DLL_PROCESS_ATTACH
:
2450 DisableThreadLibraryCalls( inst
);
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
;
2727 ULONGLONG start_time
;
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 start_time
= GetTickCount64();
2741 if (StartServiceW( service_handle
, 0, NULL
)) break;
2742 if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING
) break;
2743 if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED
) goto error
;
2744 if (GetTickCount64() - start_time
> 30000) goto error
;
2748 start_time
= GetTickCount64();
2751 if (!QueryServiceStatusEx( service_handle
, SC_STATUS_PROCESS_INFO
,
2752 (BYTE
*)&service_status
, sizeof(service_status
), &bytes
)) goto error
;
2753 if (service_status
.dwCurrentState
!= SERVICE_START_PENDING
) break;
2754 if (GetTickCount64() - start_time
> 30000) goto error
;
2758 if (service_status
.dwCurrentState
== SERVICE_RUNNING
)
2760 if (service_status
.dwProcessId
!= GetCurrentProcessId())
2761 FIXME( "driver %s was loaded into a different process\n", debugstr_us(service_name
) );
2763 status
= STATUS_SUCCESS
;
2768 WARN( "failed to start service %s\n", debugstr_us(service_name
) );
2769 status
= STATUS_UNSUCCESSFUL
;
2772 TRACE( "returning status %08x\n", status
);
2773 CloseServiceHandle( service_handle
);
2778 /***********************************************************************
2779 * ZwUnloadDriver (NTOSKRNL.EXE.@)
2781 NTSTATUS WINAPI
ZwUnloadDriver( const UNICODE_STRING
*service_name
)
2783 SERVICE_STATUS service_status
;
2784 SC_HANDLE service_handle
;
2785 ULONGLONG start_time
;
2788 TRACE( "(%s)\n", debugstr_us(service_name
) );
2790 if ((status
= open_driver( service_name
, &service_handle
)) != STATUS_SUCCESS
)
2793 if (!ControlService( service_handle
, SERVICE_CONTROL_STOP
, &service_status
))
2796 start_time
= GetTickCount64();
2799 if (!QueryServiceStatus( service_handle
, &service_status
)) goto error
;
2800 if (service_status
.dwCurrentState
!= SERVICE_STOP_PENDING
) break;
2801 if (GetTickCount64() - start_time
> 30000) goto error
;
2805 if (service_status
.dwCurrentState
== SERVICE_STOPPED
)
2807 status
= STATUS_SUCCESS
;
2812 WARN( "failed to stop service %s\n", debugstr_us(service_name
) );
2813 status
= STATUS_UNSUCCESSFUL
;
2816 TRACE( "returning status %08x\n", status
);
2817 CloseServiceHandle( service_handle
);
2822 /***********************************************************************
2823 * IoInvalidateDeviceRelations (NTOSKRNL.EXE.@)
2825 void WINAPI
IoInvalidateDeviceRelations( DEVICE_OBJECT
*device_object
, DEVICE_RELATION_TYPE type
)
2827 FIXME( "(%p, %i): stub\n", device_object
, type
);