wine  6.0.1
About: Wine is an Open Source implementation of the MS Windows API on top of X, OpenGL, and Unix. Think of Wine as a compatibility layer for running Windows programs.
  Fossies Dox: wine-6.0.1.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ntoskrnl.c
Go to the documentation of this file.
1 /*
2  * ntoskrnl.exe implementation
3  *
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
8  *
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.
13  *
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.
18  *
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
22  */
23 
24 #include <stdarg.h>
25 #include <assert.h>
26 
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 
30 #include "ntstatus.h"
31 #define WIN32_NO_STATUS
32 #include "windef.h"
33 #include "winsvc.h"
34 #include "winternl.h"
35 #include "excpt.h"
36 #include "winioctl.h"
37 #include "winbase.h"
38 #include "winreg.h"
39 #include "ntsecapi.h"
40 #include "ddk/csq.h"
41 #include "ddk/ntddk.h"
42 #include "ddk/ntifs.h"
43 #include "ddk/wdm.h"
44 #include "wine/server.h"
45 #include "wine/debug.h"
46 #include "wine/heap.h"
47 #include "wine/rbtree.h"
48 #include "wine/svcctl.h"
49 
50 #include "ntoskrnl_private.h"
51 
54 
58 
60 
61 KSYSTEM_TIME KeTickCount = { 0, 0, 0 };
62 
64 {
70 
72 
73 #define MAX_SERVICE_NAME 260
74 
79 
80 /* tid of the thread running client request */
82 
83 /* tid of the client thread */
85 
87 
88 static void *ldr_notify_cookie;
89 
91 static unsigned int load_image_notify_routine_count;
92 
94 {
97  SERVICE_STATUS_HANDLE service_handle;
98  struct wine_rb_entry entry;
99 };
100 
101 static int wine_drivers_rb_compare( const void *key, const struct wine_rb_entry *entry )
102 {
103  const struct wine_driver *driver = WINE_RB_ENTRY_VALUE( entry, const struct wine_driver, entry );
104  const UNICODE_STRING *k = key;
105 
106  return RtlCompareUnicodeString( k, &driver->driver_obj.DriverName, TRUE );
107 }
108 
110 
112 
114 {
115  static HANDLE device_manager;
116  HANDLE handle = 0, ret = device_manager;
117 
118  if (!ret)
119  {
121  {
122  req->access = SYNCHRONIZE;
123  req->attributes = 0;
124  if (!wine_server_call( req )) handle = wine_server_ptr_handle( reply->handle );
125  }
127 
128  if (!handle)
129  {
130  ERR( "failed to create the device manager\n" );
131  return 0;
132  }
133  if (!(ret = InterlockedCompareExchangePointer( &device_manager, handle, 0 )))
134  ret = handle;
135  else
136  NtClose( handle ); /* somebody beat us to it */
137  }
138  return ret;
139 }
140 
141 
143 {
146 };
147 
148 static void free_kernel_object( void *obj )
149 {
150  struct object_header *header = (struct object_header *)obj - 1;
151  HeapFree( GetProcessHeap(), 0, header );
152 }
153 
155 {
156  struct object_header *header;
157 
158  if (!(header = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*header) + size)) )
159  return NULL;
160 
161  if (handle)
162  {
164  SERVER_START_REQ( set_kernel_object_ptr )
165  {
166  req->manager = wine_server_obj_handle( get_device_manager() );
167  req->handle = wine_server_obj_handle( handle );
168  req->user_ptr = wine_server_client_ptr( header + 1 );
169  status = wine_server_call( req );
170  }
172  if (status) FIXME( "set_object_reference failed: %#x\n", status );
173  }
174 
175  header->ref = ref;
176  header->type = type;
177  return header + 1;
178 }
179 
181 
182 /***********************************************************************
183  * ObDereferenceObject (NTOSKRNL.EXE.@)
184  */
186 {
187  struct object_header *header = (struct object_header*)obj - 1;
188  LONG ref;
189 
190  if (!obj)
191  {
192  FIXME("NULL obj\n");
193  return;
194  }
195 
197 
198  ref = --header->ref;
199  TRACE( "(%p) ref=%u\n", obj, ref );
200  if (!ref)
201  {
202  if (header->type->release)
203  {
204  header->type->release( obj );
205  }
206  else
207  {
208  SERVER_START_REQ( release_kernel_object )
209  {
210  req->manager = wine_server_obj_handle( get_device_manager() );
211  req->user_ptr = wine_server_client_ptr( obj );
212  if (wine_server_call( req )) FIXME( "failed to release %p\n", obj );
213  }
215  }
216  }
217 
219 }
220 
221 void ObReferenceObject( void *obj )
222 {
223  struct object_header *header = (struct object_header*)obj - 1;
224  LONG ref;
225 
226  if (!obj)
227  {
228  FIXME("NULL obj\n");
229  return;
230  }
231 
233 
234  ref = ++header->ref;
235  TRACE( "(%p) ref=%u\n", obj, ref );
236  if (ref == 1)
237  {
239  {
240  req->manager = wine_server_obj_handle( get_device_manager() );
241  req->user_ptr = wine_server_client_ptr( obj );
242  if (wine_server_call( req )) FIXME( "failed to grab %p reference\n", obj );
243  }
245  }
246 
248 }
249 
250 /***********************************************************************
251  * ObGetObjectType (NTOSKRNL.EXE.@)
252  */
254 {
255  struct object_header *header = (struct object_header *)object - 1;
256  return header->type;
257 }
258 
259 static const POBJECT_TYPE *known_types[] =
260 {
266  &PsProcessType,
267  &PsThreadType,
269 };
270 
272 
274 {
275  void *obj;
277 
279 
281  {
282  req->manager = wine_server_obj_handle( get_device_manager() );
283  req->handle = wine_server_obj_handle( handle );
284  status = wine_server_call( req );
285  obj = wine_server_get_ptr( reply->user_ptr );
286  }
288  if (status)
289  {
291  return status;
292  }
293 
294  if (!obj)
295  {
296  char buf[256];
298  ULONG size;
299 
300  status = NtQueryObject( handle, ObjectTypeInformation, buf, sizeof(buf), &size );
301  if (status)
302  {
304  return status;
305  }
306  if (!type)
307  {
308  size_t i;
309  for (i = 0; i < ARRAY_SIZE(known_types); i++)
310  {
311  type = *known_types[i];
312  if (!RtlCompareUnicodeStrings( type->name, lstrlenW(type->name), type_info->TypeName.Buffer,
313  type_info->TypeName.Length / sizeof(WCHAR), FALSE ))
314  break;
315  }
316  if (i == ARRAY_SIZE(known_types))
317  {
318  FIXME("Unsupported type %s\n", debugstr_us(&type_info->TypeName));
320  return STATUS_INVALID_HANDLE;
321  }
322  }
323  else if (RtlCompareUnicodeStrings( type->name, lstrlenW(type->name), type_info->TypeName.Buffer,
324  type_info->TypeName.Length / sizeof(WCHAR), FALSE) )
325  {
328  }
329 
330  if (type->constructor)
331  obj = type->constructor( handle );
332  else
333  {
334  FIXME( "No constructor for type %s\n", debugstr_w(type->name) );
335  obj = alloc_kernel_object( type, handle, 0, 0 );
336  }
337  if (!obj) status = STATUS_NO_MEMORY;
338  }
340 
342  if (!status) *ret = obj;
343  return status;
344 }
345 
346 /***********************************************************************
347  * ObReferenceObjectByHandle (NTOSKRNL.EXE.@)
348  */
351  KPROCESSOR_MODE mode, void **ptr,
353 {
355 
356  TRACE( "%p %x %p %d %p %p\n", handle, access, type, mode, ptr, info );
357 
358  if (mode != KernelMode)
359  {
360  FIXME("UserMode access not implemented\n");
361  return STATUS_NOT_IMPLEMENTED;
362  }
363 
365  if (!status) ObReferenceObject( *ptr );
366  return status;
367 }
368 
369 /***********************************************************************
370  * ObOpenObjectByPointer (NTOSKRNL.EXE.@)
371  */
375 {
377 
378  TRACE( "%p %x %p %x %p %d %p\n", obj, attr, access_state, access, type, mode, handle );
379 
380  if (mode != KernelMode)
381  {
382  FIXME( "UserMode access not implemented\n" );
383  return STATUS_NOT_IMPLEMENTED;
384  }
385 
386  if (attr & ~OBJ_KERNEL_HANDLE) FIXME( "attr %#x not supported\n", attr );
387  if (access_state) FIXME( "access_state not implemented\n" );
388 
390 
391  SERVER_START_REQ( get_kernel_object_handle )
392  {
393  req->manager = wine_server_obj_handle( get_device_manager() );
394  req->user_ptr = wine_server_client_ptr( obj );
395  req->access = access;
396  if (!(status = wine_server_call( req )))
397  *handle = wine_server_ptr_handle( reply->handle );
398  }
400  return status;
401 }
402 
403 
404 static void *create_file_object( HANDLE handle );
405 
406 static const WCHAR file_type_name[] = {'F','i','l','e',0};
407 
408 static struct _OBJECT_TYPE file_type = {
411 };
412 
414 
415 static void *create_file_object( HANDLE handle )
416 {
417  FILE_OBJECT *file;
418  if (!(file = alloc_kernel_object( IoFileObjectType, handle, sizeof(*file), 0 ))) return NULL;
419  file->Type = 5; /* MSDN */
420  file->Size = sizeof(*file);
421  return file;
422 }
423 
425 
427 {
428  TRACE( "(%p %p)\n", device, irp );
429 
431 
433  irp->IoStatus.Information = 0;
435 }
436 
437 /* transfer result of IRP back to wineserver */
439 {
440  HANDLE irp_handle = context;
441  void *out_buff = irp->UserBuffer;
443 
444  if (irp->Flags & IRP_WRITE_OPERATION)
445  out_buff = NULL; /* do not transfer back input buffer */
446 
448 
450  {
451  req->handle = wine_server_obj_handle( irp_handle );
452  req->status = irp->IoStatus.u.Status;
453  req->size = irp->IoStatus.Information;
454  if (!NT_ERROR(irp->IoStatus.u.Status))
455  {
456  if (out_buff) wine_server_add_data( req, out_buff, irp->IoStatus.Information );
457  }
458  status = wine_server_call( req );
459  }
461 
463  {
464  /* IRP is complete, but server may have already ordered cancel call. In such case,
465  * it will return STATUS_MORE_PROCESSING_REQUIRED, leaving the IRP alive until
466  * cancel frees it. */
467  if (irp->Cancel)
469  else
471  }
472 
473  if (irp->UserBuffer != irp->AssociatedIrp.SystemBuffer)
474  {
475  HeapFree( GetProcessHeap(), 0, irp->UserBuffer );
476  irp->UserBuffer = NULL;
477  }
478 
480  return status;
481 }
482 
484 {
489  void *in_buff;
490 };
491 
493 {
494  LARGE_INTEGER count;
495 
497  context->handle = 0;
498 
499  KeQueryTickCount( &count ); /* update the global KeTickCount */
500 
501  context->irp = irp;
502  device->CurrentIrp = irp;
504  IoCallDriver( device, irp );
506  device->CurrentIrp = NULL;
507 }
508 
509 /* process a create request for a given file */
511 {
512  IRP *irp;
513  IO_STACK_LOCATION *irpsp;
514  FILE_OBJECT *file;
515  DEVICE_OBJECT *device = wine_server_get_ptr( context->params.create.device );
516  HANDLE handle = wine_server_ptr_handle( context->params.create.file );
517 
518  if (!(file = alloc_kernel_object( IoFileObjectType, handle, sizeof(*file), 0 )))
519  return STATUS_NO_MEMORY;
520 
521  TRACE( "device %p -> file %p\n", device, file );
522 
523  file->Type = 5; /* MSDN */
524  file->Size = sizeof(*file);
525  file->DeviceObject = device;
526 
528 
529  if (!(irp = IoAllocateIrp( device->StackSize, FALSE ))) return STATUS_NO_MEMORY;
530 
531  irpsp = IoGetNextIrpStackLocation( irp );
532  irpsp->MajorFunction = IRP_MJ_CREATE;
533  irpsp->FileObject = file;
534  irpsp->Parameters.Create.SecurityContext = NULL; /* FIXME */
535  irpsp->Parameters.Create.Options = context->params.create.options;
536  irpsp->Parameters.Create.ShareAccess = context->params.create.sharing;
537  irpsp->Parameters.Create.FileAttributes = 0;
538  irpsp->Parameters.Create.EaLength = 0;
539 
542  irp->RequestorMode = UserMode;
544  irp->UserBuffer = NULL;
545  irp->UserIosb = NULL;
546  irp->UserEvent = NULL;
547 
548  irp->Flags |= IRP_CREATE_OPERATION;
549  dispatch_irp( device, irp, context );
550 
551  return STATUS_SUCCESS;
552 }
553 
554 /* process a close request for a given file */
556 {
557  IRP *irp;
558  IO_STACK_LOCATION *irpsp;
560  FILE_OBJECT *file = wine_server_get_ptr( context->params.close.file );
561 
562  if (!file) return STATUS_INVALID_HANDLE;
563 
564  device = IoGetAttachedDevice( file->DeviceObject );
565 
566  TRACE( "device %p file %p\n", device, file );
567 
568  if (!(irp = IoAllocateIrp( device->StackSize, FALSE )))
569  {
571  return STATUS_NO_MEMORY;
572  }
573 
574  irpsp = IoGetNextIrpStackLocation( irp );
575  irpsp->MajorFunction = IRP_MJ_CLOSE;
576  irpsp->FileObject = file;
577 
580  irp->RequestorMode = UserMode;
582  irp->UserBuffer = NULL;
583  irp->UserIosb = NULL;
584  irp->UserEvent = NULL;
585 
586  irp->Flags |= IRP_CLOSE_OPERATION;
587  dispatch_irp( device, irp, context );
588 
589  return STATUS_SUCCESS;
590 }
591 
592 /* process a read request for a given device */
594 {
595  IRP *irp;
596  void *out_buff;
598  IO_STACK_LOCATION *irpsp;
600  FILE_OBJECT *file = wine_server_get_ptr( context->params.read.file );
601  ULONG out_size = context->params.read.out_size;
602 
603  if (!file) return STATUS_INVALID_HANDLE;
604 
605  device = IoGetAttachedDevice( file->DeviceObject );
606 
607  TRACE( "device %p file %p size %u\n", device, file, out_size );
608 
609  if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY;
610 
611  offset.QuadPart = context->params.read.pos;
612 
613  if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, device, out_buff, out_size,
614  &offset, NULL, NULL )))
615  {
616  HeapFree( GetProcessHeap(), 0, out_buff );
617  return STATUS_NO_MEMORY;
618  }
619 
621  irp->RequestorMode = UserMode;
622 
623  irpsp = IoGetNextIrpStackLocation( irp );
624  irpsp->FileObject = file;
625  irpsp->Parameters.Read.Key = context->params.read.key;
626 
627  irp->Flags |= IRP_READ_OPERATION;
628  irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate out_buff */
629  dispatch_irp( device, irp, context );
630 
631  return STATUS_SUCCESS;
632 }
633 
634 /* process a write request for a given device */
636 {
637  IRP *irp;
639  IO_STACK_LOCATION *irpsp;
641  FILE_OBJECT *file = wine_server_get_ptr( context->params.write.file );
642 
643  if (!file) return STATUS_INVALID_HANDLE;
644 
645  device = IoGetAttachedDevice( file->DeviceObject );
646 
647  TRACE( "device %p file %p size %u\n", device, file, context->in_size );
648 
649  offset.QuadPart = context->params.write.pos;
650 
651  if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE, device, context->in_buff, context->in_size,
652  &offset, NULL, NULL )))
653  return STATUS_NO_MEMORY;
654  context->in_buff = NULL;
655 
657  irp->RequestorMode = UserMode;
658 
659  irpsp = IoGetNextIrpStackLocation( irp );
660  irpsp->FileObject = file;
661  irpsp->Parameters.Write.Key = context->params.write.key;
662 
663  irp->Flags |= IRP_WRITE_OPERATION;
664  irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate in_buff */
665  dispatch_irp( device, irp, context );
666 
667  return STATUS_SUCCESS;
668 }
669 
670 /* process a flush request for a given device */
672 {
673  IRP *irp;
674  IO_STACK_LOCATION *irpsp;
676  FILE_OBJECT *file = wine_server_get_ptr( context->params.flush.file );
677 
678  if (!file) return STATUS_INVALID_HANDLE;
679 
680  device = IoGetAttachedDevice( file->DeviceObject );
681 
682  TRACE( "device %p file %p\n", device, file );
683 
685  NULL, NULL, NULL )))
686  return STATUS_NO_MEMORY;
687 
689  irp->RequestorMode = UserMode;
690 
691  irpsp = IoGetNextIrpStackLocation( irp );
692  irpsp->FileObject = file;
693 
694  dispatch_irp( device, irp, context );
695 
696  return STATUS_SUCCESS;
697 }
698 
699 /* process an ioctl request for a given device */
701 {
702  IO_STACK_LOCATION *irpsp;
703  IRP *irp;
704  void *out_buff = NULL;
705  void *to_free = NULL;
707  FILE_OBJECT *file = wine_server_get_ptr( context->params.ioctl.file );
708  ULONG out_size = context->params.ioctl.out_size;
709 
710  if (!file) return STATUS_INVALID_HANDLE;
711 
712  device = IoGetAttachedDevice( file->DeviceObject );
713 
714  TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n",
715  context->params.ioctl.code, device, file, context->in_size, out_size );
716 
717  if (out_size)
718  {
719  if ((context->params.ioctl.code & 3) != METHOD_BUFFERED)
720  {
721  if (context->in_size < out_size) return STATUS_INVALID_DEVICE_REQUEST;
722  context->in_size -= out_size;
723  if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY;
724  memcpy( out_buff, (char *)context->in_buff + context->in_size, out_size );
725  }
726  else if (out_size > context->in_size)
727  {
728  if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY;
729  memcpy( out_buff, context->in_buff, context->in_size );
730  to_free = context->in_buff;
731  context->in_buff = out_buff;
732  }
733  else
734  out_buff = context->in_buff;
735  }
736 
737  irp = IoBuildDeviceIoControlRequest( context->params.ioctl.code, device, context->in_buff,
738  context->in_size, out_buff, out_size, FALSE, NULL, NULL );
739  if (!irp)
740  {
741  HeapFree( GetProcessHeap(), 0, out_buff );
742  return STATUS_NO_MEMORY;
743  }
744 
745  if (out_size && (context->params.ioctl.code & 3) != METHOD_BUFFERED)
747 
748  irpsp = IoGetNextIrpStackLocation( irp );
749  irpsp->FileObject = file;
750 
752  irp->RequestorMode = UserMode;
753  irp->AssociatedIrp.SystemBuffer = context->in_buff;
754  context->in_buff = NULL;
755 
756  irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate in_buff */
757  dispatch_irp( device, irp, context );
758 
759  HeapFree( GetProcessHeap(), 0, to_free );
760  return STATUS_SUCCESS;
761 }
762 
764 {
765  void *obj = wine_server_get_ptr( context->params.free.obj );
766  TRACE( "freeing %p object\n", obj );
768  return STATUS_SUCCESS;
769 }
770 
772 {
773  IRP *irp = wine_server_get_ptr( context->params.cancel.irp );
774 
775  TRACE( "%p\n", irp );
776 
778  IoCancelIrp( irp );
780  return STATUS_SUCCESS;
781 }
782 
784 
786 {
787  NULL, /* IRP_CALL_NONE */
788  dispatch_create, /* IRP_CALL_CREATE */
789  dispatch_close, /* IRP_CALL_CLOSE */
790  dispatch_read, /* IRP_CALL_READ */
791  dispatch_write, /* IRP_CALL_WRITE */
792  dispatch_flush, /* IRP_CALL_FLUSH */
793  dispatch_ioctl, /* IRP_CALL_IOCTL */
794  dispatch_free, /* IRP_CALL_FREE */
795  dispatch_cancel /* IRP_CALL_CANCEL */
796 };
797 
798 /* helper function to update service status */
799 static void set_service_status( SERVICE_STATUS_HANDLE handle, DWORD state, DWORD accepted )
800 {
802  status.dwServiceType = SERVICE_WIN32;
803  status.dwCurrentState = state;
804  status.dwControlsAccepted = accepted;
805  status.dwWin32ExitCode = 0;
806  status.dwServiceSpecificExitCode = 0;
807  status.dwCheckPoint = 0;
808  status.dwWaitHint = (state == SERVICE_START_PENDING) ? 10000 : 0;
810 }
811 
812 static void unload_driver( struct wine_rb_entry *entry, void *context )
813 {
815  SERVICE_STATUS_HANDLE service_handle = driver->service_handle;
817 
818  if (!service_handle) return; /* not a service */
819 
820  TRACE("%s\n", debugstr_us(&driver->driver_obj.DriverName));
821 
822  if (!driver->driver_obj.DriverUnload)
823  {
824  TRACE( "driver %s does not support unloading\n", debugstr_us(&driver->driver_obj.DriverName) );
825  return;
826  }
827 
828  ldr = driver->driver_obj.DriverSection;
829 
831 
832  TRACE_(relay)( "\1Call driver unload %p (obj=%p)\n", driver->driver_obj.DriverUnload, &driver->driver_obj );
833 
834  driver->driver_obj.DriverUnload( &driver->driver_obj );
835 
836  TRACE_(relay)( "\1Ret driver unload %p (obj=%p)\n", driver->driver_obj.DriverUnload, &driver->driver_obj );
837 
838  FreeLibrary( ldr->DllBase );
839  IoDeleteDriver( &driver->driver_obj );
840 
843 }
844 
846 
847 /***********************************************************************
848  * wine_ntoskrnl_main_loop (Not a Windows API)
849  */
851 {
853  struct dispatch_context context;
855  HANDLE handles[2];
856 
857  context.handle = NULL;
858  context.irp = NULL;
859  context.in_size = 4096;
860  context.in_buff = NULL;
861 
862  /* Set the system process global before setting up the request thread trickery */
865 
867 
868  handles[0] = stop_event;
869  handles[1] = manager;
870 
871  for (;;)
872  {
873  NtCurrentTeb()->Reserved5[1] = NULL;
874  if (!context.in_buff && !(context.in_buff = HeapAlloc( GetProcessHeap(), 0, context.in_size )))
875  {
876  ERR( "failed to allocate buffer\n" );
878  goto done;
879  }
880 
881  SERVER_START_REQ( get_next_device_request )
882  {
883  req->manager = wine_server_obj_handle( manager );
884  req->prev = wine_server_obj_handle( context.handle );
885  req->user_ptr = wine_server_client_ptr( context.irp );
886  req->status = status;
887  wine_server_set_reply( req, context.in_buff, context.in_size );
888  if (!(status = wine_server_call( req )))
889  {
890  context.handle = wine_server_ptr_handle( reply->next );
891  context.params = reply->params;
892  context.in_size = reply->in_size;
893  client_tid = reply->client_tid;
894  NtCurrentTeb()->Reserved5[1] = wine_server_get_ptr( reply->client_thread );
895  }
896  else
897  {
898  context.handle = 0; /* no previous irp */
900  context.in_size = reply->in_size;
901  }
902  context.irp = NULL;
903  }
905 
906  switch (status)
907  {
908  case STATUS_SUCCESS:
909  assert( context.params.type != IRP_CALL_NONE && context.params.type < ARRAY_SIZE(dispatch_funcs) );
910  status = dispatch_funcs[context.params.type]( &context );
911  if (!context.in_buff) context.in_size = 4096;
912  break;
914  HeapFree( GetProcessHeap(), 0, context.in_buff );
915  context.in_buff = NULL;
916  /* restart with larger buffer */
917  break;
918  case STATUS_PENDING:
919  for (;;)
920  {
922  if (ret == WAIT_OBJECT_0)
923  {
924  HeapFree( GetProcessHeap(), 0, context.in_buff );
926  goto done;
927  }
928  if (ret != WAIT_IO_COMPLETION) break;
929  }
930  break;
931  }
932  }
933 
934 done:
935  /* Native PnP drivers expect that all of their devices will be removed when
936  * their unload routine is called, so we must stop the PnP manager first. */
939  return status;
940 }
941 
942 /***********************************************************************
943  * IoAllocateDriverObjectExtension (NTOSKRNL.EXE.@)
944  */
946  PVOID ClientIdentificationAddress,
947  ULONG DriverObjectExtensionSize,
948  PVOID *DriverObjectExtension )
949 {
950  FIXME( "stub: %p, %p, %u, %p\n", DriverObject, ClientIdentificationAddress,
951  DriverObjectExtensionSize, DriverObjectExtension );
952  return STATUS_NOT_IMPLEMENTED;
953 }
954 
955 
956 /***********************************************************************
957  * IoGetDriverObjectExtension (NTOSKRNL.EXE.@)
958  */
960  PVOID ClientIdentificationAddress )
961 {
962  FIXME( "stub: %p, %p\n", DriverObject, ClientIdentificationAddress );
963  return NULL;
964 }
965 
966 
967 /***********************************************************************
968  * IoInitializeIrp (NTOSKRNL.EXE.@)
969  */
971 {
972  TRACE( "%p, %u, %d\n", irp, size, stack_size );
973 
974  RtlZeroMemory( irp, size );
975 
976  irp->Type = IO_TYPE_IRP;
977  irp->Size = size;
983 }
984 
985 void WINAPI IoReuseIrp(IRP *irp, NTSTATUS iostatus)
986 {
987  UCHAR AllocationFlags;
988 
989  TRACE("irp %p, iostatus %#x.\n", irp, iostatus);
990 
991  AllocationFlags = irp->AllocationFlags;
993  irp->AllocationFlags = AllocationFlags;
994  irp->IoStatus.u.Status = iostatus;
995 }
996 
997 /***********************************************************************
998  * IoInitializeTimer (NTOSKRNL.EXE.@)
999  */
1001  PIO_TIMER_ROUTINE TimerRoutine,
1002  PVOID Context)
1003 {
1004  FIXME( "stub: %p, %p, %p\n", DeviceObject, TimerRoutine, Context );
1005  return STATUS_NOT_IMPLEMENTED;
1006 }
1007 
1008 
1009 /***********************************************************************
1010  * IoStartTimer (NTOSKRNL.EXE.@)
1011  */
1013 {
1014  FIXME( "stub: %p\n", DeviceObject );
1015 }
1016 
1017 
1018 /***********************************************************************
1019  * IoStopTimer (NTOSKRNL.EXE.@)
1020  */
1022 {
1023  FIXME( "stub: %p\n", DeviceObject );
1024 }
1025 
1026 
1027 /***********************************************************************
1028  * IoAllocateIrp (NTOSKRNL.EXE.@)
1029  */
1031 {
1032  SIZE_T size;
1033  PIRP irp;
1034  CCHAR loc_count = stack_size;
1035 
1036  TRACE( "%d, %d\n", stack_size, charge_quota );
1037 
1038  if (loc_count < 8 && loc_count != 1)
1039  loc_count = 8;
1040 
1041  size = sizeof(IRP) + loc_count * sizeof(IO_STACK_LOCATION);
1043  if (irp == NULL)
1044  return NULL;
1046  if (stack_size >= 1 && stack_size <= 8)
1048  if (charge_quota)
1050  return irp;
1051 }
1052 
1053 
1054 /***********************************************************************
1055  * IoFreeIrp (NTOSKRNL.EXE.@)
1056  */
1058 {
1059  MDL *mdl;
1060 
1061  TRACE( "%p\n", irp );
1062 
1063  mdl = irp->MdlAddress;
1064  while (mdl)
1065  {
1066  MDL *next = mdl->Next;
1067  IoFreeMdl( mdl );
1068  mdl = next;
1069  }
1070 
1071  ExFreePool( irp );
1072 }
1073 
1074 
1075 /***********************************************************************
1076  * IoAllocateErrorLogEntry (NTOSKRNL.EXE.@)
1077  */
1079 {
1080  FIXME( "stub: %p, %u\n", IoObject, EntrySize );
1081  return NULL;
1082 }
1083 
1084 
1085 /***********************************************************************
1086  * IoAllocateMdl (NTOSKRNL.EXE.@)
1087  */
1088 PMDL WINAPI IoAllocateMdl( PVOID va, ULONG length, BOOLEAN secondary, BOOLEAN charge_quota, IRP *irp )
1089 {
1090  SIZE_T mdl_size;
1091  PMDL mdl;
1092 
1093  TRACE("(%p, %u, %i, %i, %p)\n", va, length, secondary, charge_quota, irp);
1094 
1095  if (charge_quota)
1096  FIXME("Charge quota is not yet supported\n");
1097 
1098  mdl_size = sizeof(MDL) + sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length);
1099  mdl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mdl_size );
1100  if (!mdl)
1101  return NULL;
1102 
1103  MmInitializeMdl( mdl, va, length );
1104 
1105  if (!irp) return mdl;
1106 
1107  if (secondary) /* add it at the end */
1108  {
1109  MDL **pmdl = &irp->MdlAddress;
1110  while (*pmdl) pmdl = &(*pmdl)->Next;
1111  *pmdl = mdl;
1112  }
1113  else
1114  {
1115  mdl->Next = irp->MdlAddress;
1116  irp->MdlAddress = mdl;
1117  }
1118  return mdl;
1119 }
1120 
1121 
1122 /***********************************************************************
1123  * IoFreeMdl (NTOSKRNL.EXE.@)
1124  */
1126 {
1127  TRACE("%p\n", mdl);
1128  HeapFree(GetProcessHeap(), 0, mdl);
1129 }
1130 
1131 
1133 {
1136  void *context;
1137 };
1138 
1139 /***********************************************************************
1140  * IoAllocateWorkItem (NTOSKRNL.EXE.@)
1141  */
1143 {
1145 
1146  TRACE( "%p\n", device );
1147 
1148  if (!(work_item = ExAllocatePool( PagedPool, sizeof(*work_item) ))) return NULL;
1149  work_item->device = device;
1150  return work_item;
1151 }
1152 
1153 
1154 /***********************************************************************
1155  * IoFreeWorkItem (NTOSKRNL.EXE.@)
1156  */
1158 {
1159  TRACE( "%p\n", work_item );
1160  ExFreePool( work_item );
1161 }
1162 
1163 
1165 {
1167  DEVICE_OBJECT *device = work_item->device;
1168 
1169  TRACE( "%p: calling %p(%p %p)\n", work_item, work_item->worker, device, work_item->context );
1170  work_item->worker( device, work_item->context );
1171  TRACE( "done\n" );
1172 
1174 }
1175 
1176 /***********************************************************************
1177  * IoQueueWorkItem (NTOSKRNL.EXE.@)
1178  */
1180  WORK_QUEUE_TYPE type, void *context )
1181 {
1182  TRACE( "%p %p %u %p\n", work_item, worker, type, context );
1183 
1184  ObReferenceObject( work_item->device );
1185  work_item->worker = worker;
1186  work_item->context = context;
1188 }
1189 
1190 /***********************************************************************
1191  * IoGetAttachedDevice (NTOSKRNL.EXE.@)
1192  */
1194 {
1195  DEVICE_OBJECT *result = device;
1196 
1197  TRACE( "(%p)\n", device );
1198 
1199  while (result->AttachedDevice)
1200  result = result->AttachedDevice;
1201 
1202  return result;
1203 }
1204 
1206 {
1207  device->AttachedDevice = NULL;
1208 }
1209 
1210 /***********************************************************************
1211  * IoAttachDeviceToDeviceStack (NTOSKRNL.EXE.@)
1212  */
1214  DEVICE_OBJECT *target )
1215 {
1216  TRACE( "%p, %p\n", source, target );
1217  target = IoGetAttachedDevice( target );
1218  target->AttachedDevice = source;
1219  source->StackSize = target->StackSize + 1;
1220  return target;
1221 }
1222 
1223 /***********************************************************************
1224  * IoBuildDeviceIoControlRequest (NTOSKRNL.EXE.@)
1225  */
1227  PVOID in_buff, ULONG in_len,
1228  PVOID out_buff, ULONG out_len,
1229  BOOLEAN internal, PKEVENT event,
1231 {
1232  PIRP irp;
1233  PIO_STACK_LOCATION irpsp;
1234  MDL *mdl;
1235 
1236  TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
1237  code, device, in_buff, in_len, out_buff, out_len, internal, event, iosb );
1238 
1239  if (device == NULL)
1240  return NULL;
1241 
1242  irp = IoAllocateIrp( device->StackSize, FALSE );
1243  if (irp == NULL)
1244  return NULL;
1245 
1246  irpsp = IoGetNextIrpStackLocation( irp );
1248  irpsp->Parameters.DeviceIoControl.IoControlCode = code;
1249  irpsp->Parameters.DeviceIoControl.InputBufferLength = in_len;
1250  irpsp->Parameters.DeviceIoControl.OutputBufferLength = out_len;
1251  irpsp->DeviceObject = NULL;
1252  irpsp->CompletionRoutine = NULL;
1253 
1254  switch (code & 3)
1255  {
1256  case METHOD_BUFFERED:
1257  irp->AssociatedIrp.SystemBuffer = in_buff;
1258  break;
1259  case METHOD_IN_DIRECT:
1260  case METHOD_OUT_DIRECT:
1261  irp->AssociatedIrp.SystemBuffer = in_buff;
1262 
1263  mdl = IoAllocateMdl( out_buff, out_len, FALSE, FALSE, irp );
1264  if (!mdl)
1265  {
1266  IoFreeIrp( irp );
1267  return NULL;
1268  }
1269 
1271  mdl->MappedSystemVa = out_buff;
1272  break;
1273  case METHOD_NEITHER:
1274  irpsp->Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
1275  break;
1276  }
1277 
1278  irp->RequestorMode = KernelMode;
1279  irp->UserBuffer = out_buff;
1280  irp->UserIosb = iosb;
1281  irp->UserEvent = event;
1283  return irp;
1284 }
1285 
1286 /***********************************************************************
1287  * IoBuildAsynchronousFsdRequest (NTOSKRNL.EXE.@)
1288  */
1290  void *buffer, ULONG length, LARGE_INTEGER *startoffset,
1292 {
1293  PIRP irp;
1294  PIO_STACK_LOCATION irpsp;
1295 
1296  TRACE( "(%d %p %p %d %p %p)\n", majorfunc, device, buffer, length, startoffset, iosb );
1297 
1298  if (!(irp = IoAllocateIrp( device->StackSize, FALSE ))) return NULL;
1299 
1300  irpsp = IoGetNextIrpStackLocation( irp );
1301  irpsp->MajorFunction = majorfunc;
1302  irpsp->DeviceObject = NULL;
1303  irpsp->CompletionRoutine = NULL;
1304 
1306 
1307  if (device->Flags & DO_DIRECT_IO)
1308  {
1309  MDL *mdl = IoAllocateMdl( buffer, length, FALSE, FALSE, irp );
1310  if (!mdl)
1311  {
1312  IoFreeIrp( irp );
1313  return NULL;
1314  }
1315 
1317  mdl->MappedSystemVa = buffer;
1318  }
1319 
1320  switch (majorfunc)
1321  {
1322  case IRP_MJ_READ:
1323  irpsp->Parameters.Read.Length = length;
1324  irpsp->Parameters.Read.ByteOffset.QuadPart = startoffset ? startoffset->QuadPart : 0;
1325  break;
1326  case IRP_MJ_WRITE:
1327  irpsp->Parameters.Write.Length = length;
1328  irpsp->Parameters.Write.ByteOffset.QuadPart = startoffset ? startoffset->QuadPart : 0;
1329  break;
1330  }
1331  irp->RequestorMode = KernelMode;
1332  irp->UserIosb = iosb;
1333  irp->UserEvent = NULL;
1334  irp->UserBuffer = buffer;
1336  return irp;
1337 }
1338 
1339 
1340 
1341 /***********************************************************************
1342  * IoBuildSynchronousFsdRequest (NTOSKRNL.EXE.@)
1343  */
1345  PVOID buffer, ULONG length, PLARGE_INTEGER startoffset,
1347 {
1348  IRP *irp;
1349 
1350  TRACE("(%d %p %p %d %p %p)\n", majorfunc, device, buffer, length, startoffset, iosb);
1351 
1352  irp = IoBuildAsynchronousFsdRequest( majorfunc, device, buffer, length, startoffset, iosb );
1353  if (!irp) return NULL;
1354 
1355  irp->UserEvent = event;
1356  return irp;
1357 }
1358 
1360 {
1361  static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0};
1362  WCHAR *str;
1363 
1364  /* Check what prefix is present */
1365  if (wcsncmp( name, servicesW, lstrlenW(servicesW) ) == 0)
1366  {
1367  FIXME( "Driver name %s is malformed as the keypath\n", debugstr_w(name) );
1369  return;
1370  }
1371  if (wcsncmp( name, driverW, lstrlenW(driverW) ) == 0)
1372  name += lstrlenW(driverW);
1373  else
1374  FIXME( "Driver name %s does not properly begin with \\Driver\\\n", debugstr_w(name) );
1375 
1376  str = HeapAlloc( GetProcessHeap(), 0, sizeof(servicesW) + lstrlenW(name)*sizeof(WCHAR));
1377  lstrcpyW( str, servicesW );
1378  lstrcatW( str, name );
1380 }
1381 
1382 
1384 {
1385  TRACE( "(%p, %p)\n", device, irp );
1389 }
1390 
1391 
1392 static void free_driver_object( void *obj )
1393 {
1394  struct wine_driver *driver = obj;
1395  RtlFreeUnicodeString( &driver->driver_obj.DriverName );
1396  RtlFreeUnicodeString( &driver->driver_obj.DriverExtension->ServiceKeyName );
1398 }
1399 
1400 static const WCHAR driver_type_name[] = {'D','r','i','v','e','r',0};
1401 
1402 static struct _OBJECT_TYPE driver_type =
1403 {
1405  NULL,
1407 };
1408 
1410 
1411 
1412 /***********************************************************************
1413  * IoCreateDriver (NTOSKRNL.EXE.@)
1414  */
1416 {
1417  struct wine_driver *driver;
1418  NTSTATUS status;
1419  unsigned int i;
1420 
1421  TRACE("(%s, %p)\n", debugstr_us(name), init);
1422 
1423  if (!(driver = alloc_kernel_object( IoDriverObjectType, NULL, sizeof(*driver), 1 )))
1424  return STATUS_NO_MEMORY;
1425 
1426  if ((status = RtlDuplicateUnicodeString( 1, name, &driver->driver_obj.DriverName )))
1427  {
1429  return status;
1430  }
1431 
1432  driver->driver_obj.Size = sizeof(driver->driver_obj);
1433  driver->driver_obj.DriverInit = init;
1434  driver->driver_obj.DriverExtension = &driver->driver_extension;
1435  driver->driver_extension.DriverObject = &driver->driver_obj;
1436  build_driver_keypath( driver->driver_obj.DriverName.Buffer, &driver->driver_extension.ServiceKeyName );
1437  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1438  driver->driver_obj.MajorFunction[i] = unhandled_irp;
1439 
1441  if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry ))
1442  ERR( "failed to insert driver %s in tree\n", debugstr_us(name) );
1444 
1445  status = driver->driver_obj.DriverInit( &driver->driver_obj, &driver->driver_extension.ServiceKeyName );
1446  if (status)
1447  {
1448  IoDeleteDriver( &driver->driver_obj );
1449  return status;
1450  }
1451 
1452  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1453  {
1454  if (driver->driver_obj.MajorFunction[i]) continue;
1455  driver->driver_obj.MajorFunction[i] = unhandled_irp;
1456  }
1457 
1458  return STATUS_SUCCESS;
1459 }
1460 
1461 
1462 /***********************************************************************
1463  * IoDeleteDriver (NTOSKRNL.EXE.@)
1464  */
1465 void WINAPI IoDeleteDriver( DRIVER_OBJECT *driver_object )
1466 {
1467  TRACE( "(%p)\n", driver_object );
1468 
1470  wine_rb_remove_key( &wine_drivers, &driver_object->DriverName );
1472 
1473  ObDereferenceObject( driver_object );
1474 }
1475 
1476 
1477 static const WCHAR device_type_name[] = {'D','e','v','i','c','e',0};
1478 
1479 static struct _OBJECT_TYPE device_type =
1480 {
1482 };
1483 
1485 
1486 
1487 /***********************************************************************
1488  * IoCreateDevice (NTOSKRNL.EXE.@)
1489  */
1492  ULONG characteristics, BOOLEAN exclusive,
1493  DEVICE_OBJECT **ret_device )
1494 {
1495  static const WCHAR auto_format[] = {'\\','D','e','v','i','c','e','\\','%','0','8','x',0};
1496  NTSTATUS status;
1497  struct wine_device *wine_device;
1500  static unsigned int auto_idx = 0;
1501  WCHAR autoW[17];
1502 
1503  TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n",
1504  driver, ext_size, debugstr_us(name), type, characteristics, exclusive, ret_device );
1505 
1506  if (!(wine_device = alloc_kernel_object( IoDeviceObjectType, NULL, sizeof(struct wine_device) + ext_size, 1 )))
1507  return STATUS_NO_MEMORY;
1509 
1510  device->DriverObject = driver;
1511  device->DeviceExtension = wine_device + 1;
1512  device->DeviceType = type;
1513  device->StackSize = 1;
1514 
1515  if (characteristics & FILE_AUTOGENERATED_DEVICE_NAME)
1516  {
1517  do
1518  {
1519  swprintf( autoW, ARRAY_SIZE(autoW), auto_format, auto_idx++ );
1521  {
1522  req->rootdir = 0;
1523  req->manager = wine_server_obj_handle( manager );
1524  req->user_ptr = wine_server_client_ptr( device );
1525  wine_server_add_data( req, autoW, lstrlenW(autoW) * sizeof(WCHAR) );
1526  status = wine_server_call( req );
1527  }
1529  } while (status == STATUS_OBJECT_NAME_COLLISION);
1530  }
1531  else
1532  {
1534  {
1535  req->rootdir = 0;
1536  req->manager = wine_server_obj_handle( manager );
1537  req->user_ptr = wine_server_client_ptr( device );
1538  if (name) wine_server_add_data( req, name->Buffer, name->Length );
1539  status = wine_server_call( req );
1540  }
1542  }
1543 
1544  if (status)
1545  {
1547  return status;
1548  }
1549 
1550  device->NextDevice = driver->DeviceObject;
1551  driver->DeviceObject = device;
1552 
1553  *ret_device = device;
1554  return STATUS_SUCCESS;
1555 }
1556 
1557 
1558 /***********************************************************************
1559  * IoDeleteDevice (NTOSKRNL.EXE.@)
1560  */
1562 {
1563  NTSTATUS status;
1564 
1565  TRACE( "%p\n", device );
1566 
1568  {
1569  req->manager = wine_server_obj_handle( get_device_manager() );
1570  req->device = wine_server_client_ptr( device );
1571  status = wine_server_call( req );
1572  }
1574 
1575  if (status == STATUS_SUCCESS)
1576  {
1578  DEVICE_OBJECT **prev = &device->DriverObject->DeviceObject;
1579  while (*prev && *prev != device) prev = &(*prev)->NextDevice;
1580  if (*prev) *prev = (*prev)->NextDevice;
1583  }
1584 }
1585 
1586 
1587 /***********************************************************************
1588  * IoCreateSymbolicLink (NTOSKRNL.EXE.@)
1589  */
1591 {
1592  HANDLE handle;
1594  NTSTATUS ret;
1595 
1596  attr.Length = sizeof(attr);
1597  attr.RootDirectory = 0;
1598  attr.ObjectName = name;
1600  attr.SecurityDescriptor = NULL;
1601  attr.SecurityQualityOfService = NULL;
1602 
1603  TRACE( "%s -> %s\n", debugstr_us(name), debugstr_us(target) );
1604  if (!(ret = NtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, target )))
1605  NtClose( handle );
1606  return ret;
1607 }
1608 
1609 
1610 /***********************************************************************
1611  * IoCreateUnprotectedSymbolicLink (NTOSKRNL.EXE.@)
1612  */
1614 {
1615  HANDLE handle;
1617  NTSTATUS ret;
1618 
1619  attr.Length = sizeof(attr);
1620  attr.RootDirectory = 0;
1621  attr.ObjectName = name;
1623  attr.SecurityDescriptor = NULL;
1624  attr.SecurityQualityOfService = NULL;
1625 
1626  TRACE( "%s -> %s\n", debugstr_us(name), debugstr_us(target) );
1627  if (!(ret = NtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, target )))
1628  NtClose( handle );
1629  return ret;
1630 }
1631 
1632 
1633 /***********************************************************************
1634  * IoDeleteSymbolicLink (NTOSKRNL.EXE.@)
1635  */
1637 {
1638  HANDLE handle;
1640  NTSTATUS status;
1641 
1642  attr.Length = sizeof(attr);
1643  attr.RootDirectory = 0;
1644  attr.ObjectName = name;
1645  attr.Attributes = OBJ_CASE_INSENSITIVE;
1646  attr.SecurityDescriptor = NULL;
1647  attr.SecurityQualityOfService = NULL;
1648 
1649  if (!(status = NtOpenSymbolicLinkObject( &handle, 0, &attr )))
1650  {
1651  NtMakeTemporaryObject( handle );
1652  NtClose( handle );
1653  }
1654  return status;
1655 }
1656 
1657 /***********************************************************************
1658  * IoGetDeviceInterfaces (NTOSKRNL.EXE.@)
1659  */
1660 NTSTATUS WINAPI IoGetDeviceInterfaces( const GUID *InterfaceClassGuid,
1661  PDEVICE_OBJECT PhysicalDeviceObject,
1662  ULONG Flags, PWSTR *SymbolicLinkList )
1663 {
1664  FIXME( "stub: %s %p %x %p\n", debugstr_guid(InterfaceClassGuid),
1665  PhysicalDeviceObject, Flags, SymbolicLinkList );
1666  return STATUS_NOT_IMPLEMENTED;
1667 }
1668 
1669 
1670 /***********************************************************************
1671  * IoGetDeviceObjectPointer (NTOSKRNL.EXE.@)
1672  */
1674 {
1675  static DEVICE_OBJECT stub_device;
1676  static DRIVER_OBJECT stub_driver;
1677 
1678  FIXME( "stub: %s %x %p %p\n", debugstr_us(name), access, file, device );
1679 
1680  stub_device.StackSize = 0x80; /* minimum value to appease SecuROM 5.x */
1681  stub_device.DriverObject = &stub_driver;
1682 
1683  *file = NULL;
1684  *device = &stub_device;
1685 
1686  return STATUS_SUCCESS;
1687 }
1688 
1689 /***********************************************************************
1690  * IoCallDriver (NTOSKRNL.EXE.@)
1691  */
1693 {
1694  PDRIVER_DISPATCH dispatch;
1695  IO_STACK_LOCATION *irpsp;
1696  NTSTATUS status;
1697 
1698  --irp->CurrentLocation;
1699  irpsp = --irp->Tail.Overlay.s.u2.CurrentStackLocation;
1700  irpsp->DeviceObject = device;
1701  dispatch = device->DriverObject->MajorFunction[irpsp->MajorFunction];
1702 
1703  TRACE_(relay)( "\1Call driver dispatch %p (device=%p,irp=%p)\n", dispatch, device, irp );
1704 
1705  status = dispatch( device, irp );
1706 
1707  TRACE_(relay)( "\1Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
1708  dispatch, device, irp, status );
1709 
1710  return status;
1711 }
1712 
1713 
1714 /***********************************************************************
1715  * IofCallDriver (NTOSKRNL.EXE.@)
1716  */
1719 {
1720  TRACE( "%p %p\n", device, irp );
1721  return IoCallDriver( device, irp );
1722 }
1723 
1724 
1725 /***********************************************************************
1726  * IoGetRelatedDeviceObject (NTOSKRNL.EXE.@)
1727  */
1729 {
1730  FIXME( "stub: %p\n", obj );
1731  return NULL;
1732 }
1733 
1735 
1736 /***********************************************************************
1737  * IoGetConfigurationInformation (NTOSKRNL.EXE.@)
1738  */
1740 {
1741  FIXME( "partial stub\n" );
1742  /* FIXME: return actual devices on system */
1743  return &configuration_information;
1744 }
1745 
1746 /***********************************************************************
1747  * IoGetStackLimits (NTOSKRNL.EXE.@)
1748  */
1750 {
1751  TEB *teb = NtCurrentTeb();
1752 
1753  TRACE( "%p %p\n", low, high );
1754 
1755  *low = (DWORD_PTR)teb->Tib.StackLimit;
1756  *high = (DWORD_PTR)teb->Tib.StackBase;
1757 }
1758 
1759 /***********************************************************************
1760  * IoIsWdmVersionAvailable (NTOSKRNL.EXE.@)
1761  */
1763 {
1764  DWORD version;
1765  DWORD major;
1766  DWORD minor;
1767 
1768  TRACE( "%d, 0x%X\n", MajorVersion, MinorVersion );
1769 
1770  version = GetVersion();
1771  major = LOBYTE(version);
1772  minor = HIBYTE(LOWORD(version));
1773 
1774  if (MajorVersion == 6 && MinorVersion == 0)
1775  {
1776  /* Windows Vista, Windows Server 2008, Windows 7 */
1777  }
1778  else if (MajorVersion == 1)
1779  {
1780  if (MinorVersion == 0x30)
1781  {
1782  /* Windows server 2003 */
1783  MajorVersion = 6;
1784  MinorVersion = 0;
1785  }
1786  else if (MinorVersion == 0x20)
1787  {
1788  /* Windows XP */
1789  MajorVersion = 5;
1790  MinorVersion = 1;
1791  }
1792  else if (MinorVersion == 0x10)
1793  {
1794  /* Windows 2000 */
1795  MajorVersion = 5;
1796  MinorVersion = 0;
1797  }
1798  else if (MinorVersion == 0x05)
1799  {
1800  /* Windows ME */
1801  MajorVersion = 4;
1802  MinorVersion = 0x5a;
1803  }
1804  else if (MinorVersion == 0x00)
1805  {
1806  /* Windows 98 */
1807  MajorVersion = 4;
1808  MinorVersion = 0x0a;
1809  }
1810  else
1811  {
1812  FIXME( "unknown major %d minor 0x%X\n", MajorVersion, MinorVersion );
1813  return FALSE;
1814  }
1815  }
1816  else
1817  {
1818  FIXME( "unknown major %d minor 0x%X\n", MajorVersion, MinorVersion );
1819  return FALSE;
1820  }
1821  return major > MajorVersion || (major == MajorVersion && minor >= MinorVersion);
1822 }
1823 
1824 /***********************************************************************
1825  * IoQueryDeviceDescription (NTOSKRNL.EXE.@)
1826  */
1828  PULONG cnum, PCONFIGURATION_TYPE ptype, PULONG pnum,
1830 {
1831  FIXME( "(%p %p %p %p %p %p %p %p)\n", itype, bus, ctype, cnum, ptype, pnum, callout, context);
1832  return STATUS_NOT_IMPLEMENTED;
1833 }
1834 
1835 /***********************************************************************
1836  * IoRegisterDriverReinitialization (NTOSKRNL.EXE.@)
1837  */
1839 {
1840  FIXME( "stub: %p %p %p\n", obj, reinit, context );
1841 }
1842 
1843 /***********************************************************************
1844  * IoRegisterBootDriverReinitialization (NTOSKRNL.EXE.@)
1845  */
1847 {
1848  FIXME("driver %p, proc %p, ctx %p, stub!\n", driver, proc, ctx);
1849 }
1850 
1851 /***********************************************************************
1852  * IoRegisterShutdownNotification (NTOSKRNL.EXE.@)
1853  */
1855 {
1856  FIXME( "stub: %p\n", obj );
1857  return STATUS_SUCCESS;
1858 }
1859 
1860 
1861 /***********************************************************************
1862  * IoUnregisterShutdownNotification (NTOSKRNL.EXE.@)
1863  */
1865 {
1866  FIXME( "stub: %p\n", obj );
1867 }
1868 
1869 
1870 /***********************************************************************
1871  * IoReportResourceForDetection (NTOSKRNL.EXE.@)
1872  */
1874  DEVICE_OBJECT *dev_obj, CM_RESOURCE_LIST *dev_list, ULONG dev_size,
1875  BOOLEAN *conflict )
1876 {
1877  FIXME( "(%p, %p, %u, %p, %p, %u, %p): stub\n", drv_obj, drv_list, drv_size,
1878  dev_obj, dev_list, dev_size, conflict );
1879 
1880  return STATUS_NOT_IMPLEMENTED;
1881 }
1882 
1883 
1884 /***********************************************************************
1885  * IoReportResourceUsage (NTOSKRNL.EXE.@)
1886  */
1888  ULONG drv_size, DRIVER_OBJECT *dev_obj, CM_RESOURCE_LIST *dev_list,
1889  ULONG dev_size, BOOLEAN overwrite, BOOLEAN *conflict )
1890 {
1891  FIXME( "(%s, %p, %p, %u, %p, %p, %u, %d, %p): stub\n", debugstr_us(name),
1892  drv_obj, drv_list, drv_size, dev_obj, dev_list, dev_size, overwrite, conflict );
1893 
1894  return STATUS_NOT_IMPLEMENTED;
1895 }
1896 
1897 
1898 /***********************************************************************
1899  * IoCompleteRequest (NTOSKRNL.EXE.@)
1900  */
1901 VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
1902 {
1903  IO_STACK_LOCATION *irpsp;
1904  PIO_COMPLETION_ROUTINE routine;
1905  NTSTATUS status, stat;
1907  int call_flag = 0;
1908 
1909  TRACE( "%p %u\n", irp, priority_boost );
1910 
1911  status = irp->IoStatus.u.Status;
1912  while (irp->CurrentLocation <= irp->StackCount)
1913  {
1914  irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
1915  routine = irpsp->CompletionRoutine;
1916  call_flag = 0;
1917  if (routine)
1918  {
1919  if ((irpsp->Control & SL_INVOKE_ON_SUCCESS) && STATUS_SUCCESS == status)
1920  call_flag = 1;
1921  if ((irpsp->Control & SL_INVOKE_ON_ERROR) && STATUS_SUCCESS != status)
1922  call_flag = 1;
1923  if ((irpsp->Control & SL_INVOKE_ON_CANCEL) && irp->Cancel)
1924  call_flag = 1;
1925  }
1926  ++irp->CurrentLocation;
1927  ++irp->Tail.Overlay.s.u2.CurrentStackLocation;
1928  if (irp->CurrentLocation <= irp->StackCount)
1929  device = IoGetCurrentIrpStackLocation(irp)->DeviceObject;
1930  else
1931  device = NULL;
1932  if (call_flag)
1933  {
1934  TRACE( "calling %p( %p, %p, %p )\n", routine, device, irp, irpsp->Context );
1935  stat = routine( device, irp, irpsp->Context );
1936  TRACE( "CompletionRoutine returned %x\n", stat );
1938  return;
1939  }
1940  }
1941 
1942  if (irp->Flags & IRP_DEALLOCATE_BUFFER)
1944  if (irp->UserEvent) KeSetEvent( irp->UserEvent, IO_NO_INCREMENT, FALSE );
1945 
1946  IoFreeIrp( irp );
1947 }
1948 
1949 
1950 /***********************************************************************
1951  * IofCompleteRequest (NTOSKRNL.EXE.@)
1952  */
1954 void FASTCALL IofCompleteRequest( IRP *irp, UCHAR priority_boost )
1955 {
1956  TRACE( "%p %u\n", irp, priority_boost );
1957  IoCompleteRequest( irp, priority_boost );
1958 }
1959 
1960 
1961 /***********************************************************************
1962  * IoCancelIrp (NTOSKRNL.EXE.@)
1963  */
1965 {
1966  PDRIVER_CANCEL cancel_routine;
1967  KIRQL irql;
1968 
1969  TRACE( "(%p)\n", irp );
1970 
1971  IoAcquireCancelSpinLock( &irql );
1972  irp->Cancel = TRUE;
1973  if (!(cancel_routine = IoSetCancelRoutine( irp, NULL )))
1974  {
1976  return FALSE;
1977  }
1978 
1979  /* CancelRoutine is responsible for calling IoReleaseCancelSpinLock */
1980  irp->CancelIrql = irql;
1981  cancel_routine( IoGetCurrentIrpStackLocation(irp)->DeviceObject, irp );
1982  return TRUE;
1983 }
1984 
1985 
1986 /***********************************************************************
1987  * InterlockedCompareExchange (NTOSKRNL.EXE.@)
1988  */
1991 {
1992  return InterlockedCompareExchange( dest, xchg, compare );
1993 }
1994 
1995 
1996 /***********************************************************************
1997  * InterlockedDecrement (NTOSKRNL.EXE.@)
1998  */
2001 {
2002  return InterlockedDecrement( dest );
2003 }
2004 
2005 
2006 /***********************************************************************
2007  * InterlockedExchange (NTOSKRNL.EXE.@)
2008  */
2011 {
2012  return InterlockedExchange( dest, val );
2013 }
2014 
2015 
2016 /***********************************************************************
2017  * InterlockedExchangeAdd (NTOSKRNL.EXE.@)
2018  */
2021 {
2022  return InterlockedExchangeAdd( dest, incr );
2023 }
2024 
2025 
2026 /***********************************************************************
2027  * InterlockedIncrement (NTOSKRNL.EXE.@)
2028  */
2031 {
2032  return InterlockedIncrement( dest );
2033 }
2034 
2035 
2036 /***********************************************************************
2037  * ExAllocatePool (NTOSKRNL.EXE.@)
2038  */
2040 {
2041  return ExAllocatePoolWithTag( type, size, 0 );
2042 }
2043 
2044 
2045 /***********************************************************************
2046  * ExAllocatePoolWithQuota (NTOSKRNL.EXE.@)
2047  */
2049 {
2050  return ExAllocatePoolWithTag( type, size, 0 );
2051 }
2052 
2053 
2054 /***********************************************************************
2055  * ExAllocatePoolWithTag (NTOSKRNL.EXE.@)
2056  */
2058 {
2059  /* FIXME: handle page alignment constraints */
2060  void *ret = HeapAlloc( ntoskrnl_heap, 0, size );
2061  TRACE( "%lu pool %u -> %p\n", size, type, ret );
2062  return ret;
2063 }
2064 
2065 
2066 /***********************************************************************
2067  * ExAllocatePoolWithQuotaTag (NTOSKRNL.EXE.@)
2068  */
2070 {
2071  return ExAllocatePoolWithTag( type, size, tag );
2072 }
2073 
2074 
2075 /***********************************************************************
2076  * ExCreateCallback (NTOSKRNL.EXE.@)
2077  */
2079  BOOLEAN create, BOOLEAN allow_multiple)
2080 {
2081  FIXME("(%p, %p, %u, %u): stub\n", obj, attr, create, allow_multiple);
2082 
2083  return STATUS_SUCCESS;
2084 }
2085 
2087  PCALLBACK_FUNCTION callback_function, void *callback_context)
2088 {
2089  FIXME("callback_object %p, callback_function %p, callback_context %p stub.\n",
2090  callback_object, callback_function, callback_context);
2091 
2092  return (void *)0xdeadbeef;
2093 }
2094 
2095 void WINAPI ExUnregisterCallback(void *callback_registration)
2096 {
2097  FIXME("callback_registration %p stub.\n", callback_registration);
2098 }
2099 
2100 /***********************************************************************
2101  * ExFreePool (NTOSKRNL.EXE.@)
2102  */
2103 void WINAPI ExFreePool( void *ptr )
2104 {
2105  ExFreePoolWithTag( ptr, 0 );
2106 }
2107 
2108 
2109 /***********************************************************************
2110  * ExFreePoolWithTag (NTOSKRNL.EXE.@)
2111  */
2112 void WINAPI ExFreePoolWithTag( void *ptr, ULONG tag )
2113 {
2114  TRACE( "%p\n", ptr );
2115  HeapFree( ntoskrnl_heap, 0, ptr );
2116 }
2117 
2120 {
2121 
2122  RtlInitializeSListHead( &lookaside->u.ListHead );
2123  lookaside->Depth = 4;
2124  lookaside->MaximumDepth = 256;
2125  lookaside->TotalAllocates = 0;
2126  lookaside->u2.AllocateMisses = 0;
2127  lookaside->TotalFrees = 0;
2128  lookaside->u3.FreeMisses = 0;
2129  lookaside->Type = type;
2130  lookaside->Tag = tag;
2131  lookaside->Size = size;
2132  lookaside->u4.Allocate = allocate ? allocate : ExAllocatePoolWithTag;
2133  lookaside->u5.Free = free ? free : ExFreePool;
2134  lookaside->LastTotalAllocates = 0;
2135  lookaside->u6.LastAllocateMisses = 0;
2136 
2137  /* FIXME: insert in global list of lookadside lists */
2138 }
2139 
2140 /***********************************************************************
2141  * ExInitializeNPagedLookasideList (NTOSKRNL.EXE.@)
2142  */
2144  PALLOCATE_FUNCTION allocate,
2146  ULONG flags,
2147  SIZE_T size,
2148  ULONG tag,
2149  USHORT depth)
2150 {
2151  TRACE( "%p, %p, %p, %u, %lu, %u, %u\n", lookaside, allocate, free, flags, size, tag, depth );
2152  initialize_lookaside_list( &lookaside->L, allocate, free, NonPagedPool | flags, size, tag );
2153 }
2154 
2155 /***********************************************************************
2156  * ExInitializePagedLookasideList (NTOSKRNL.EXE.@)
2157  */
2159  PALLOCATE_FUNCTION allocate,
2161  ULONG flags,
2162  SIZE_T size,
2163  ULONG tag,
2164  USHORT depth)
2165 {
2166  TRACE( "%p, %p, %p, %u, %lu, %u, %u\n", lookaside, allocate, free, flags, size, tag, depth );
2167  initialize_lookaside_list( &lookaside->L, allocate, free, PagedPool | flags, size, tag );
2168 }
2169 
2170 static void delete_lookaside_list( GENERAL_LOOKASIDE *lookaside )
2171 {
2172  void *entry;
2173  while ((entry = RtlInterlockedPopEntrySList(&lookaside->u.ListHead)))
2174  lookaside->u5.FreeEx(entry, (LOOKASIDE_LIST_EX*)lookaside);
2175 }
2176 
2177 /***********************************************************************
2178  * ExDeleteNPagedLookasideList (NTOSKRNL.EXE.@)
2179  */
2181 {
2182  TRACE( "%p\n", lookaside );
2183  delete_lookaside_list( &lookaside->L );
2184 }
2185 
2186 
2187 /***********************************************************************
2188  * ExDeletePagedLookasideList (NTOSKRNL.EXE.@)
2189  */
2191 {
2192  TRACE( "%p\n", lookaside );
2193  delete_lookaside_list( &lookaside->L );
2194 }
2195 
2196 /***********************************************************************
2197  * ExInitializeZone (NTOSKRNL.EXE.@)
2198  */
2200  ULONG BlockSize,
2201  PVOID InitialSegment,
2202  ULONG InitialSegmentSize)
2203 {
2204  FIXME( "stub: %p, %u, %p, %u\n", Zone, BlockSize, InitialSegment, InitialSegmentSize );
2205  return STATUS_NOT_IMPLEMENTED;
2206 }
2207 
2208 /***********************************************************************
2209 * FsRtlIsNameInExpression (NTOSKRNL.EXE.@)
2210 */
2212  BOOLEAN ignore, PWCH upcase)
2213 {
2214  FIXME("stub: %p %p %d %p\n", expression, name, ignore, upcase);
2215  return FALSE;
2216 }
2217 
2218 /***********************************************************************
2219 * FsRtlRegisterUncProvider (NTOSKRNL.EXE.@)
2220 */
2222  BOOLEAN MailslotsSupported)
2223 {
2224  FIXME("(%p %p %d): stub\n", MupHandle, RedirDevName, MailslotsSupported);
2225  return STATUS_NOT_IMPLEMENTED;
2226 }
2227 
2228 
2229 static void *create_process_object( HANDLE handle )
2230 {
2232 
2233  if (!(process = alloc_kernel_object( PsProcessType, handle, sizeof(*process), 0 ))) return NULL;
2234 
2235  process->header.Type = 3;
2236  process->header.WaitListHead.Blink = INVALID_HANDLE_VALUE; /* mark as kernel object */
2237  NtQueryInformationProcess( handle, ProcessBasicInformation, &process->info, sizeof(process->info), NULL );
2238  IsWow64Process( handle, &process->wow64 );
2239  return process;
2240 }
2241 
2242 static const WCHAR process_type_name[] = {'P','r','o','c','e','s','s',0};
2243 
2244 static struct _OBJECT_TYPE process_type =
2245 {
2248 };
2249 
2251 
2252 
2253 /***********************************************************************
2254  * IoGetCurrentProcess / PsGetCurrentProcess (NTOSKRNL.EXE.@)
2255  */
2257 {
2258  return KeGetCurrentThread()->process;
2259 }
2260 
2261 /***********************************************************************
2262  * PsLookupProcessByProcessId (NTOSKRNL.EXE.@)
2263  */
2265 {
2266  NTSTATUS status;
2267  HANDLE handle;
2268 
2269  TRACE( "(%p %p)\n", processid, process );
2270 
2271  if (!(handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, HandleToUlong(processid) )))
2272  return STATUS_INVALID_PARAMETER;
2273 
2275 
2276  NtClose( handle );
2277  return status;
2278 }
2279 
2280 /*********************************************************************
2281  * PsGetProcessId (NTOSKRNL.@)
2282  */
2284 {
2285  TRACE( "%p -> %lx\n", process, process->info.UniqueProcessId );
2286  return (HANDLE)process->info.UniqueProcessId;
2287 }
2288 
2289 /*********************************************************************
2290  * PsGetProcessInheritedFromUniqueProcessId (NTOSKRNL.@)
2291  */
2293 {
2294  HANDLE id = (HANDLE)process->info.InheritedFromUniqueProcessId;
2295  TRACE( "%p -> %p\n", process, id );
2296  return id;
2297 }
2298 
2299 static void *create_thread_object( HANDLE handle )
2300 {
2302  struct _KTHREAD *thread;
2303  HANDLE process;
2304 
2305  if (!(thread = alloc_kernel_object( PsThreadType, handle, sizeof(*thread), 0 ))) return NULL;
2306 
2307  thread->header.Type = 6;
2308  thread->header.WaitListHead.Blink = INVALID_HANDLE_VALUE; /* mark as kernel object */
2309  thread->user_affinity = 0;
2310 
2311  if (!NtQueryInformationThread( handle, ThreadBasicInformation, &info, sizeof(info), NULL ))
2312  {
2313  thread->id = info.ClientId;
2315  {
2317  NtClose( process );
2318  }
2319  }
2320 
2321 
2322  return thread;
2323 }
2324 
2325 static const WCHAR thread_type_name[] = {'T','h','r','e','a','d',0};
2326 
2327 static struct _OBJECT_TYPE thread_type =
2328 {
2331 };
2332 
2334 
2335 
2336 /***********************************************************************
2337  * KeGetCurrentThread / PsGetCurrentThread (NTOSKRNL.EXE.@)
2338  */
2340 {
2341  struct _KTHREAD *thread = NtCurrentTeb()->Reserved5[1];
2342 
2343  if (!thread)
2344  {
2345  HANDLE handle = GetCurrentThread();
2346 
2347  /* FIXME: we shouldn't need it, GetCurrentThread() should be client thread already */
2350 
2351  kernel_object_from_handle( handle, PsThreadType, (void**)&thread );
2352  if (handle != GetCurrentThread()) NtClose( handle );
2353 
2354  NtCurrentTeb()->Reserved5[1] = thread;
2355  }
2356 
2357  return thread;
2358 }
2359 
2360 /*****************************************************
2361  * PsLookupThreadByThreadId (NTOSKRNL.EXE.@)
2362  */
2364 {
2366  CLIENT_ID cid;
2367  NTSTATUS status;
2368  HANDLE handle;
2369 
2370  TRACE( "(%p %p)\n", threadid, thread );
2371 
2372  cid.UniqueProcess = 0;
2373  cid.UniqueThread = threadid;
2375  status = NtOpenThread( &handle, THREAD_QUERY_INFORMATION, &attr, &cid );
2376  if (status) return status;
2377 
2379 
2380  NtClose( handle );
2381  return status;
2382 }
2383 
2384 /*********************************************************************
2385  * PsGetThreadId (NTOSKRNL.@)
2386  */
2388 {
2389  TRACE( "%p -> %p\n", thread, thread->kthread.id.UniqueThread );
2390  return thread->kthread.id.UniqueThread;
2391 }
2392 
2393 /*********************************************************************
2394  * PsGetThreadProcessId (NTOSKRNL.@)
2395  */
2397 {
2398  TRACE( "%p -> %p\n", thread, thread->kthread.id.UniqueProcess );
2399  return thread->kthread.id.UniqueProcess;
2400 }
2401 
2402 /***********************************************************************
2403  * KeInsertQueue (NTOSKRNL.EXE.@)
2404  */
2406 {
2407  FIXME( "stub: %p %p\n", Queue, Entry );
2408  return 0;
2409 }
2410 
2411 /**********************************************************************
2412  * KeQueryActiveProcessors (NTOSKRNL.EXE.@)
2413  *
2414  * Return the active Processors as bitmask
2415  *
2416  * RETURNS
2417  * active Processors as bitmask
2418  *
2419  */
2421 {
2422  DWORD_PTR affinity_mask;
2423 
2424  GetProcessAffinityMask( GetCurrentProcess(), NULL, &affinity_mask);
2425  return affinity_mask;
2426 }
2427 
2429 {
2430  TRACE("group_number %u.\n", group_number);
2431 
2432  return GetActiveProcessorCount(group_number);
2433 }
2434 
2435 /**********************************************************************
2436  * KeQueryInterruptTime (NTOSKRNL.EXE.@)
2437  *
2438  * Return the interrupt time count
2439  *
2440  */
2442 {
2443  LARGE_INTEGER totaltime;
2444 
2445  KeQueryTickCount(&totaltime);
2446  return totaltime.QuadPart;
2447 }
2448 
2449 
2450 /***********************************************************************
2451  * KeQuerySystemTime (NTOSKRNL.EXE.@)
2452  */
2454 {
2456 }
2457 
2458 
2459 /***********************************************************************
2460  * KeQueryTickCount (NTOSKRNL.EXE.@)
2461  */
2463 {
2464  count->QuadPart = NtGetTickCount();
2465  /* update the global variable too */
2466  KeTickCount.LowPart = count->u.LowPart;
2467  KeTickCount.High1Time = count->u.HighPart;
2468  KeTickCount.High2Time = count->u.HighPart;
2469 }
2470 
2471 
2472 /***********************************************************************
2473  * KeQueryTimeIncrement (NTOSKRNL.EXE.@)
2474  */
2476 {
2477  return 10000;
2478 }
2479 
2480 
2481 /***********************************************************************
2482  * KeSetPriorityThread (NTOSKRNL.EXE.@)
2483  */
2485 {
2486  FIXME("(%p %d)\n", Thread, Priority);
2487  return Priority;
2488 }
2489 
2490 /***********************************************************************
2491  * KeSetSystemAffinityThread (NTOSKRNL.EXE.@)
2492  */
2494 {
2495  KeSetSystemAffinityThreadEx(affinity);
2496 }
2497 
2499 {
2500  DWORD_PTR system_affinity = KeQueryActiveProcessors();
2502  GROUP_AFFINITY old, new;
2503 
2504  TRACE("affinity %#lx.\n", affinity);
2505 
2506  affinity &= system_affinity;
2507 
2509  &old, sizeof(old), NULL);
2510 
2511  if (old.Mask != system_affinity)
2512  thread->user_affinity = old.Mask;
2513 
2514  memset(&new, 0, sizeof(new));
2515  new.Mask = affinity;
2516 
2517  return NtSetInformationThread(GetCurrentThread(), ThreadGroupInformation, &new, sizeof(new))
2518  ? 0 : thread->user_affinity;
2519 }
2520 
2521 
2522 /***********************************************************************
2523  * KeRevertToUserAffinityThread (NTOSKRNL.EXE.@)
2524  */
2526 {
2528 }
2529 
2531 {
2532  DWORD_PTR system_affinity = KeQueryActiveProcessors();
2534  GROUP_AFFINITY new;
2535 
2536  TRACE("affinity %#lx.\n", affinity);
2537 
2538  affinity &= system_affinity;
2539 
2540  memset(&new, 0, sizeof(new));
2541  new.Mask = affinity ? affinity
2542  : (thread->user_affinity ? thread->user_affinity : system_affinity);
2543 
2545  thread->user_affinity = affinity;
2546 }
2547 
2548 /***********************************************************************
2549  * IoRegisterFileSystem (NTOSKRNL.EXE.@)
2550  */
2552 {
2553  FIXME("(%p): stub\n", DeviceObject);
2554 }
2555 
2556 /***********************************************************************
2557  * KeExpandKernelStackAndCalloutEx (NTOSKRNL.EXE.@)
2558  */
2560  BOOLEAN wait, void *context)
2561 {
2562  WARN("(%p %p %lu %x %p) semi-stub: ignoring stack expand\n", callout, parameter, size, wait, context);
2563  callout(parameter);
2564  return STATUS_SUCCESS;
2565 }
2566 
2567 /***********************************************************************
2568  * KeExpandKernelStackAndCallout (NTOSKRNL.EXE.@)
2569  */
2571 {
2572  return KeExpandKernelStackAndCalloutEx(callout, parameter, size, TRUE, NULL);
2573 }
2574 
2575 /***********************************************************************
2576 * IoUnregisterFileSystem (NTOSKRNL.EXE.@)
2577 */
2579 {
2580  FIXME("(%p): stub\n", DeviceObject);
2581 }
2582 
2583 /***********************************************************************
2584  * MmAllocateNonCachedMemory (NTOSKRNL.EXE.@)
2585  */
2587 {
2588  TRACE( "%lu\n", size );
2590 }
2591 
2592 /***********************************************************************
2593  * MmAllocateContiguousMemory (NTOSKRNL.EXE.@)
2594  */
2596 {
2597  FIXME( "%lu, %s stub\n", size, wine_dbgstr_longlong(highest_valid_address.QuadPart) );
2598  return NULL;
2599 }
2600 
2601 /***********************************************************************
2602  * MmAllocateContiguousMemorySpecifyCache (NTOSKRNL.EXE.@)
2603  */
2605  PHYSICAL_ADDRESS lowest_valid_address,
2606  PHYSICAL_ADDRESS highest_valid_address,
2607  PHYSICAL_ADDRESS BoundaryAddressMultiple,
2608  MEMORY_CACHING_TYPE CacheType )
2609 {
2610  FIXME(": stub\n");
2611  return NULL;
2612 }
2613 
2614 /***********************************************************************
2615  * MmAllocatePagesForMdl (NTOSKRNL.EXE.@)
2616  */
2618  PHYSICAL_ADDRESS skipbytes, SIZE_T size)
2619 {
2620  FIXME("%s %s %s %lu: stub\n", wine_dbgstr_longlong(lowaddress.QuadPart), wine_dbgstr_longlong(highaddress.QuadPart),
2621  wine_dbgstr_longlong(skipbytes.QuadPart), size);
2622  return NULL;
2623 }
2624 
2625 /***********************************************************************
2626  * MmBuildMdlForNonPagedPool (NTOSKRNL.EXE.@)
2627  */
2629 {
2630  FIXME("stub: %p\n", mdl);
2631 }
2632 
2633 /***********************************************************************
2634  * MmCreateSection (NTOSKRNL.EXE.@)
2635  */
2637  LARGE_INTEGER *size, ULONG protect, ULONG alloc_attr,
2639 {
2640  FIXME("%p %#x %p %s %#x %#x %p %p: stub\n", handle, access, attr,
2641  wine_dbgstr_longlong(size->QuadPart), protect, alloc_attr, file, file_obj);
2642  return STATUS_NOT_IMPLEMENTED;
2643 }
2644 
2645 /***********************************************************************
2646  * MmFreeNonCachedMemory (NTOSKRNL.EXE.@)
2647  */
2649 {
2650  TRACE( "%p %lu\n", addr, size );
2651  VirtualFree( addr, 0, MEM_RELEASE );
2652 }
2653 
2654 /***********************************************************************
2655  * MmIsAddressValid (NTOSKRNL.EXE.@)
2656  *
2657  * Check if the process can access the virtual address without a pagefault
2658  *
2659  * PARAMS
2660  * VirtualAddress [I] Address to check
2661  *
2662  * RETURNS
2663  * Failure: FALSE
2664  * Success: TRUE (Accessing the Address works without a Pagefault)
2665  *
2666  */
2668 {
2669  TRACE("(%p)\n", VirtualAddress);
2670  return !IsBadReadPtr(VirtualAddress, 1);
2671 }
2672 
2673 /***********************************************************************
2674  * MmMapIoSpace (NTOSKRNL.EXE.@)
2675  */
2676 PVOID WINAPI MmMapIoSpace( PHYSICAL_ADDRESS PhysicalAddress, DWORD NumberOfBytes, DWORD CacheType )
2677 {
2678  FIXME( "stub: 0x%08x%08x, %d, %d\n", PhysicalAddress.u.HighPart, PhysicalAddress.u.LowPart, NumberOfBytes, CacheType );
2679  return NULL;
2680 }
2681 
2682 
2683 /***********************************************************************
2684  * MmLockPagableSectionByHandle (NTOSKRNL.EXE.@)
2685  */
2687 {
2688  FIXME("stub %p\n", ImageSectionHandle);
2689 }
2690 
2691 /***********************************************************************
2692  * MmMapLockedPagesSpecifyCache (NTOSKRNL.EXE.@)
2693  */
2695  PVOID BaseAddress, ULONG BugCheckOnFailure, MM_PAGE_PRIORITY Priority)
2696 {
2697  FIXME("(%p, %u, %u, %p, %u, %u): stub\n", MemoryDescriptorList, AccessMode, CacheType, BaseAddress, BugCheckOnFailure, Priority);
2698 
2699  return NULL;
2700 }
2701 
2702 /***********************************************************************
2703  * MmUnmapLockedPages (NTOSKRNL.EXE.@)
2704  */
2705 void WINAPI MmUnmapLockedPages( void *base, MDL *mdl )
2706 {
2707  FIXME( "(%p %p_\n", base, mdl );
2708 }
2709 
2710 /***********************************************************************
2711  * MmUnlockPagableImageSection (NTOSKRNL.EXE.@)
2712  */
2714 {
2715  FIXME("stub %p\n", ImageSectionHandle);
2716 }
2717 
2718 /***********************************************************************
2719  * MmPageEntireDriver (NTOSKRNL.EXE.@)
2720  */
2722 {
2723  TRACE("%p\n", AddrInSection);
2724  return AddrInSection;
2725 }
2726 
2727 
2728 /***********************************************************************
2729  * MmProbeAndLockPages (NTOSKRNL.EXE.@)
2730  */
2731 void WINAPI MmProbeAndLockPages(PMDLX MemoryDescriptorList, KPROCESSOR_MODE AccessMode, LOCK_OPERATION Operation)
2732 {
2733  FIXME("(%p, %u, %u): stub\n", MemoryDescriptorList, AccessMode, Operation);
2734 }
2735 
2736 
2737 /***********************************************************************
2738  * MmResetDriverPaging (NTOSKRNL.EXE.@)
2739  */
2740 void WINAPI MmResetDriverPaging(PVOID AddrInSection)
2741 {
2742  TRACE("%p\n", AddrInSection);
2743 }
2744 
2745 
2746 /***********************************************************************
2747  * MmUnlockPages (NTOSKRNL.EXE.@)
2748  */
2749 void WINAPI MmUnlockPages(PMDLX MemoryDescriptorList)
2750 {
2751  FIXME("(%p): stub\n", MemoryDescriptorList);
2752 }
2753 
2754 
2755 /***********************************************************************
2756  * MmUnmapIoSpace (NTOSKRNL.EXE.@)
2757  */
2758 VOID WINAPI MmUnmapIoSpace( PVOID BaseAddress, SIZE_T NumberOfBytes )
2759 {
2760  FIXME( "stub: %p, %lu\n", BaseAddress, NumberOfBytes );
2761 }
2762 
2763 
2764  /***********************************************************************
2765  * ObReferenceObjectByName (NTOSKRNL.EXE.@)
2766  */
2768  ULONG Attributes,
2769  ACCESS_STATE *AccessState,
2770  ACCESS_MASK DesiredAccess,
2771  POBJECT_TYPE ObjectType,
2772  KPROCESSOR_MODE AccessMode,
2773  void *ParseContext,
2774  void **Object)
2775 {
2776  struct wine_driver *driver;
2777  struct wine_rb_entry *entry;
2778 
2779  TRACE("mostly-stub:%s %i %p %i %p %i %p %p\n", debugstr_us(ObjectName),
2780  Attributes, AccessState, DesiredAccess, ObjectType, AccessMode,
2781  ParseContext, Object);
2782 
2783  if (AccessState) FIXME("Unhandled AccessState\n");
2784  if (DesiredAccess) FIXME("Unhandled DesiredAccess\n");
2785  if (ParseContext) FIXME("Unhandled ParseContext\n");
2786  if (ObjectType) FIXME("Unhandled ObjectType\n");
2787 
2788  if (AccessMode != KernelMode)
2789  {
2790  FIXME("UserMode access not implemented\n");
2791  return STATUS_NOT_IMPLEMENTED;
2792  }
2793 
2795  entry = wine_rb_get(&wine_drivers, ObjectName);
2797  if (!entry)
2798  {
2799  FIXME("Object (%s) not found, may not be tracked.\n", debugstr_us(ObjectName));
2800  return STATUS_NOT_IMPLEMENTED;
2801  }
2802 
2803  driver = WINE_RB_ENTRY_VALUE(entry, struct wine_driver, entry);
2804  ObReferenceObject( *Object = &driver->driver_obj );
2805  return STATUS_SUCCESS;
2806 }
2807 
2808 
2809 /********************************************************************
2810  * ObOpenObjectByName (NTOSKRNL.EXE.@)
2811  */
2813  KPROCESSOR_MODE mode, ACCESS_STATE *access_state,
2814  ACCESS_MASK access, PVOID ctx, HANDLE *handle)
2815 {
2816  NTSTATUS status;
2817  void *object;
2818 
2819  TRACE( "attr(%p %s %x) %p %u %p %u %p %p\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
2820  attr->Attributes, type, mode, access_state, access, ctx, handle );
2821 
2822  if (mode != KernelMode)
2823  {
2824  FIXME( "UserMode access not implemented\n" );
2825  return STATUS_NOT_IMPLEMENTED;
2826  }
2827 
2828  if (attr->RootDirectory) FIXME( "RootDirectory unhandled\n" );
2829 
2830  status = ObReferenceObjectByName(attr->ObjectName, attr->Attributes, access_state, access, type, mode, ctx, &object );
2831  if (status != STATUS_SUCCESS)
2832  return status;
2833 
2834  status = ObOpenObjectByPointer(object, attr->Attributes, access_state, access, type, mode, handle);
2835 
2836  ObDereferenceObject(object);
2837  return status;
2838 }
2839 
2840 
2841 /***********************************************************************
2842  * ObReferenceObjectByPointer (NTOSKRNL.EXE.@)
2843  */
2847 {
2848  FIXME("(%p, %x, %p, %d): stub\n", obj, access, type, mode);
2849 
2850  return STATUS_NOT_IMPLEMENTED;
2851 }
2852 
2853 
2854 /***********************************************************************
2855  * ObfReferenceObject (NTOSKRNL.EXE.@)
2856  */
2859 {
2861 }
2862 
2863 
2864 /***********************************************************************
2865  * ObfDereferenceObject (NTOSKRNL.EXE.@)
2866  */
2869 {
2871 }
2872 
2873 /***********************************************************************
2874  * ObRegisterCallbacks (NTOSKRNL.EXE.@)
2875  */
2877 {
2878  FIXME( "callback %p, handle %p.\n", callback, handle );
2879 
2880  if(handle)
2881  *handle = UlongToHandle(0xdeadbeaf);
2882 
2883  return STATUS_SUCCESS;
2884 }
2885 
2886 /***********************************************************************
2887  * ObUnRegisterCallbacks (NTOSKRNL.EXE.@)
2888  */
2889 void WINAPI ObUnRegisterCallbacks(void *handle)
2890 {
2891  FIXME( "stub: %p\n", handle );
2892 }
2893 
2894 /***********************************************************************
2895  * ObGetFilterVersion (NTOSKRNL.EXE.@)
2896  */
2898 {
2899  FIXME( "stub:\n" );
2900 
2902 }
2903 
2904 /***********************************************************************
2905  * IoGetAttachedDeviceReference (NTOSKRNL.EXE.@)
2906  */
2908 {
2910  ObReferenceObject( result );
2911  return result;
2912 }
2913 
2914 
2915 /***********************************************************************
2916  * PsCreateSystemThread (NTOSKRNL.EXE.@)
2917  */
2918 NTSTATUS WINAPI PsCreateSystemThread(PHANDLE ThreadHandle, ULONG DesiredAccess,
2919  POBJECT_ATTRIBUTES ObjectAttributes,
2920  HANDLE ProcessHandle, PCLIENT_ID ClientId,
2921  PKSTART_ROUTINE StartRoutine, PVOID StartContext)
2922 {
2923  if (!ProcessHandle) ProcessHandle = GetCurrentProcess();
2924  return RtlCreateUserThread(ProcessHandle, 0, FALSE, 0, 0,
2925  0, StartRoutine, StartContext,
2926  ThreadHandle, ClientId);
2927 }
2928 
2929 /***********************************************************************
2930  * PsGetCurrentProcessId (NTOSKRNL.EXE.@)
2931  */
2933 {
2935 }
2936 
2937 
2938 /***********************************************************************
2939  * PsGetCurrentThreadId (NTOSKRNL.EXE.@)
2940  */
2942 {
2944 }
2945 
2946 
2947 /***********************************************************************
2948  * PsIsSystemThread (NTOSKRNL.EXE.@)
2949  */
2951 {
2952  return thread->kthread.process == PsInitialSystemProcess;
2953 }
2954 
2955 
2956 /***********************************************************************
2957  * PsGetVersion (NTOSKRNL.EXE.@)
2958  */
2960 {
2962 
2963  info.dwOSVersionInfoSize = sizeof(info);
2964  RtlGetVersion( &info );
2965  if (major) *major = info.dwMajorVersion;
2966  if (minor) *minor = info.dwMinorVersion;
2967  if (build) *build = info.dwBuildNumber;
2968 
2969  if (version)
2970  {
2971 #if 0 /* FIXME: GameGuard passes an uninitialized pointer in version->Buffer */
2972  size_t len = min( lstrlenW(info.szCSDVersion)*sizeof(WCHAR), version->MaximumLength );
2973  memcpy( version->Buffer, info.szCSDVersion, len );
2974  if (len < version->MaximumLength) version->Buffer[len / sizeof(WCHAR)] = 0;
2975  version->Length = len;
2976 #endif
2977  }
2978  return TRUE;
2979 }
2980 
2981 
2982 /***********************************************************************
2983  * PsImpersonateClient (NTOSKRNL.EXE.@)
2984  */
2986  BOOLEAN EffectiveOnly, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2987 {
2988  FIXME("(%p, %p, %u, %u, %u): stub\n", Thread, Token, CopyOnOpen, EffectiveOnly, ImpersonationLevel);
2989 
2990  return STATUS_NOT_IMPLEMENTED;
2991 }
2992 
2993 
2994 /***********************************************************************
2995  * PsRevertToSelf (NTOSKRNL.EXE.@)
2996  */
2998 {
2999  FIXME("\n");
3000 }
3001 
3002 
3003 /***********************************************************************
3004  * PsSetCreateProcessNotifyRoutine (NTOSKRNL.EXE.@)
3005  */
3007 {
3008  FIXME( "stub: %p %d\n", callback, remove );
3009  return STATUS_SUCCESS;
3010 }
3011 
3012 
3013 /***********************************************************************
3014  * PsSetCreateProcessNotifyRoutineEx (NTOSKRNL.EXE.@)
3015  */
3017 {
3018  FIXME( "stub: %p %d\n", callback, remove );
3019  return STATUS_SUCCESS;
3020 }
3021 
3022 
3023 /***********************************************************************
3024  * PsSetCreateThreadNotifyRoutine (NTOSKRNL.EXE.@)
3025  */
3027 {
3028  FIXME( "stub: %p\n", NotifyRoutine );
3029  return STATUS_SUCCESS;
3030 }
3031 
3032 
3033 /***********************************************************************
3034  * PsRemoveCreateThreadNotifyRoutine (NTOSKRNL.EXE.@)
3035  */
3037 {
3038  FIXME( "stub: %p\n", NotifyRoutine );
3039  return STATUS_SUCCESS;
3040 }
3041 
3042 
3043 /***********************************************************************
3044  * PsRemoveLoadImageNotifyRoutine (NTOSKRNL.EXE.@)
3045  */
3047  {
3048  unsigned int i;
3049 
3050  TRACE("routine %p.\n", routine);
3051 
3052  for (i = 0; i < load_image_notify_routine_count; ++i)
3053  if (load_image_notify_routines[i] == routine)
3054  {
3058  return STATUS_SUCCESS;
3059  }
3061  }
3062 
3063 
3064 /***********************************************************************
3065  * PsReferenceProcessFilePointer (NTOSKRNL.EXE.@)
3066  */
3068 {
3069  FIXME("%p %p\n", process, file);
3070  return STATUS_NOT_IMPLEMENTED;
3071 }
3072 
3073 
3074 /***********************************************************************
3075  * PsTerminateSystemThread (NTOSKRNL.EXE.@)
3076  */
3078 {
3079  TRACE("status %#x.\n", status);
3080  ExitThread( status );
3081 }
3082 
3083 
3084 /***********************************************************************
3085  * PsSuspendProcess (NTOSKRNL.EXE.@)
3086  */
3088 {
3089  FIXME("stub: %p\n", process);
3090  return STATUS_NOT_IMPLEMENTED;
3091 }
3092 
3093 
3094 /***********************************************************************
3095  * PsResumeProcess (NTOSKRNL.EXE.@)
3096  */
3098 {
3099  FIXME("stub: %p\n", process);
3100  return STATUS_NOT_IMPLEMENTED;
3101 }
3102 
3103 
3104 /***********************************************************************
3105  * MmGetSystemRoutineAddress (NTOSKRNL.EXE.@)
3106  */
3108 {
3109  HMODULE hMod;
3110  STRING routineNameA;
3111  PVOID pFunc = NULL;
3112 
3113  static const WCHAR ntoskrnlW[] = {'n','t','o','s','k','r','n','l','.','e','x','e',0};
3114  static const WCHAR halW[] = {'h','a','l','.','d','l','l',0};
3115 
3116  if (!SystemRoutineName) return NULL;
3117 
3118  if (RtlUnicodeStringToAnsiString( &routineNameA, SystemRoutineName, TRUE ) == STATUS_SUCCESS)
3119  {
3120  /* We only support functions exported from ntoskrnl.exe or hal.dll */
3121  hMod = GetModuleHandleW( ntoskrnlW );
3122  pFunc = GetProcAddress( hMod, routineNameA.Buffer );
3123  if (!pFunc)
3124  {
3125  hMod = GetModuleHandleW( halW );
3126 
3127  if (hMod) pFunc = GetProcAddress( hMod, routineNameA.Buffer );
3128  }
3129  RtlFreeAnsiString( &routineNameA );
3130  }
3131 
3132  if (pFunc)
3133  TRACE( "%s -> %p\n", debugstr_us(SystemRoutineName), pFunc );
3134  else
3135  FIXME( "%s not found\n", debugstr_us(SystemRoutineName) );
3136  return pFunc;
3137 }
3138 
3139 /***********************************************************************
3140  * MmIsThisAnNtAsSystem (NTOSKRNL.EXE.@)
3141  */
3143 {
3144  TRACE("\n");
3145  return FALSE;
3146 }
3147 
3148 /***********************************************************************
3149  * MmProtectMdlSystemAddress (NTOSKRNL.EXE.@)
3150  */
3151 NTSTATUS WINAPI MmProtectMdlSystemAddress(PMDL MemoryDescriptorList, ULONG NewProtect)
3152 {
3153  FIXME("(%p, %u) stub\n", MemoryDescriptorList, NewProtect);
3154  return STATUS_SUCCESS;
3155 }
3156 
3157 /***********************************************************************
3158  * MmQuerySystemSize (NTOSKRNL.EXE.@)
3159  */
3161 {
3162  FIXME("stub\n");
3163  return MmLargeSystem;
3164 }
3165 
3166 /***********************************************************************
3167  * KeInitializeDpc (NTOSKRNL.EXE.@)
3168  */
3169 void WINAPI KeInitializeDpc(KDPC *dpc, PKDEFERRED_ROUTINE deferred_routine, void *deferred_context)
3170 {
3171  FIXME("dpc %p, deferred_routine %p, deferred_context %p semi-stub.\n",
3172  dpc, deferred_routine, deferred_context);
3173 
3174  dpc->DeferredRoutine = deferred_routine;
3175  dpc->DeferredContext = deferred_context;
3176 }
3177 
3178 /***********************************************************************
3179  * KeSetImportanceDpc (NTOSKRNL.EXE.@)
3180  */
3182 {
3183  FIXME("%p, %d stub\n", dpc, importance);
3184 }
3185 
3186 /***********************************************************************
3187  * KeSetTargetProcessorDpc (NTOSKRNL.EXE.@)
3188  */
3190 {
3191  FIXME("%p, %d stub\n", dpc, number);
3192 }
3193 
3194 /***********************************************************************
3195  * READ_REGISTER_BUFFER_UCHAR (NTOSKRNL.EXE.@)
3196  */
3198 {
3199  FIXME("stub\n");
3200 }
3201 
3202 /*****************************************************
3203  * IoWMIRegistrationControl (NTOSKRNL.EXE.@)
3204  */
3206 {
3207  FIXME("(%p %u) stub\n", DeviceObject, Action);
3208  return STATUS_SUCCESS;
3209 }
3210 
3211 /*****************************************************
3212  * IoWMIOpenBlock (NTOSKRNL.EXE.@)
3213  */
3214 NTSTATUS WINAPI IoWMIOpenBlock(LPCGUID guid, ULONG desired_access, PVOID *data_block_obj)
3215 {
3216  FIXME("(%p %u %p) stub\n", guid, desired_access, data_block_obj);
3217  return STATUS_NOT_IMPLEMENTED;
3218 }
3219 
3220 /*****************************************************
3221  * PsSetLoadImageNotifyRoutine (NTOSKRNL.EXE.@)
3222  */
3224 {
3225  FIXME("routine %p, semi-stub.\n", routine);
3226 
3229 
3231 
3232  return STATUS_SUCCESS;
3233 }
3234 
3235 /*****************************************************
3236  * IoSetThreadHardErrorMode (NTOSKRNL.EXE.@)
3237  */
3239 {
3240  FIXME("stub\n");
3241  return FALSE;
3242 }
3243 
3244 /*****************************************************
3245  * Ke386IoSetAccessProcess (NTOSKRNL.EXE.@)
3246  */
3248 {
3249  FIXME("(%p %d) stub\n", process, flag);
3250  return FALSE;
3251 }
3252 
3253 /*****************************************************
3254  * Ke386SetIoAccessMap (NTOSKRNL.EXE.@)
3255  */
3257 {
3258  FIXME("(%d %p) stub\n", flag, buffer);
3259  return FALSE;
3260 }
3261 
3262 /*****************************************************
3263  * IoStartNextPacket (NTOSKRNL.EXE.@)
3264  */
3266 {
3267  FIXME("(%p %d) stub\n", deviceobject, cancelable);
3268 }
3269 
3270 /*****************************************************
3271  * ObQueryNameString (NTOSKRNL.EXE.@)
3272  */
3274 {
3275  HANDLE handle;
3276  NTSTATUS ret;
3277 
3278  TRACE("object %p, name %p, size %u, ret_size %p.\n", object, name, size, ret_size);
3279 
3280  if ((ret = ObOpenObjectByPointer( object, 0, NULL, 0, NULL, KernelMode, &handle )))
3281  return ret;
3282  ret = NtQueryObject( handle, ObjectNameInformation, name, size, ret_size );
3283 
3284  NtClose( handle );
3285  return ret;
3286 }
3287 
3288 /*****************************************************
3289  * IoRegisterPlugPlayNotification (NTOSKRNL.EXE.@)
3290  */
3293  PVOID context, PVOID *notification)
3294 {
3295  FIXME("(%u %u %p %p %p %p %p) stub\n", category, flags, data, driver, callback, context, notification);
3296  return STATUS_SUCCESS;
3297 }
3298 
3299 /*****************************************************
3300  * IoUnregisterPlugPlayNotification (NTOSKRNL.EXE.@)
3301  */
3303 {
3304  FIXME("stub: %p\n", notification);
3305  return STATUS_SUCCESS;
3306 }
3307 
3308 /*****************************************************
3309  * IoCsqInitialize (NTOSKRNL.EXE.@)
3310  */
3314 {
3315  FIXME("(%p %p %p %p %p %p %p) stub\n",
3316  csq, insert_irp, remove_irp, peek_irp, acquire_lock, release_lock, complete_irp);
3317  return STATUS_SUCCESS;
3318 }
3319 
3320 /***********************************************************************
3321  * KeEnterCriticalRegion (NTOSKRNL.EXE.@)
3322  */
3324 {
3325  TRACE( "semi-stub\n" );
3327 }
3328 
3329 /***********************************************************************
3330  * KeLeaveCriticalRegion (NTOSKRNL.EXE.@)
3331  */
3333 {
3334  TRACE( "semi-stub\n" );
3336 }
3337 
3338 /***********************************************************************
3339  * KeAreApcsDisabled (NTOSKRNL.@)
3340  */
3342 {
3343  unsigned int critical_region = KeGetCurrentThread()->critical_region;
3344  TRACE( "%u\n", critical_region );
3345  return !!critical_region;
3346 }
3347 
3348 /***********************************************************************
3349  * KeBugCheck (NTOSKRNL.@)
3350  */
3352 {
3353  KeBugCheckEx(code, 0, 0, 0, 0);
3354 }
3355 
3356 /***********************************************************************
3357  * KeBugCheckEx (NTOSKRNL.@)
3358  */
3360 {
3361  ERR( "%x %lx %lx %lx %lx\n", code, param1, param2, param3, param4 );
3362  ExitProcess( code );
3363 }
3364 
3365 /***********************************************************************
3366  * ProbeForRead (NTOSKRNL.EXE.@)
3367  */
3368 void WINAPI ProbeForRead(void *address, SIZE_T length, ULONG alignment)
3369 {
3370  FIXME("(%p %lu %u) stub\n", address, length, alignment);
3371 }
3372 
3373 /***********************************************************************
3374  * ProbeForWrite (NTOSKRNL.EXE.@)
3375  */
3376 void WINAPI ProbeForWrite(void *address, SIZE_T length, ULONG alignment)
3377 {
3378  FIXME("(%p %lu %u) stub\n", address, length, alignment);
3379 }
3380 
3381 /***********************************************************************
3382  * CmRegisterCallback (NTOSKRNL.EXE.@)
3383  */
3384 NTSTATUS WINAPI CmRegisterCallback(EX_CALLBACK_FUNCTION *function, void *context, LARGE_INTEGER *cookie)
3385 {
3386  FIXME("(%p %p %p): stub\n", function, context, cookie);
3387  return STATUS_NOT_IMPLEMENTED;
3388 }
3389 
3390 /***********************************************************************
3391  * CmUnRegisterCallback (NTOSKRNL.EXE.@)
3392  */
3394 {
3395  FIXME("(%s): stub\n", wine_dbgstr_longlong(cookie.QuadPart));
3396  return STATUS_NOT_IMPLEMENTED;
3397 }
3398 
3399 /***********************************************************************
3400  * IoAttachDevice (NTOSKRNL.EXE.@)
3401  */
3403 {
3404  FIXME("(%p, %s, %p): stub\n", source, debugstr_us(target), attached);
3405  return STATUS_NOT_IMPLEMENTED;
3406 }
3407 
3408 
3409 static NTSTATUS open_driver( const UNICODE_STRING *service_name, SC_HANDLE *service )
3410 {
3411  QUERY_SERVICE_CONFIGW *service_config = NULL;
3412  SC_HANDLE manager_handle;
3413  DWORD config_size = 0;
3414  WCHAR *name;
3415 
3416  if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, service_name->Length + sizeof(WCHAR) )))
3417  return STATUS_NO_MEMORY;
3418 
3419  memcpy( name, service_name->Buffer, service_name->Length );
3420  name[ service_name->Length / sizeof(WCHAR) ] = 0;
3421 
3423  {
3424  FIXME( "service name %s is not a keypath\n", debugstr_us(service_name) );
3425  RtlFreeHeap( GetProcessHeap(), 0, name );
3426  return STATUS_NOT_IMPLEMENTED;
3427  }
3428 
3430  {
3431  WARN( "failed to connect to service manager\n" );
3432  RtlFreeHeap( GetProcessHeap(), 0, name );
3433  return STATUS_NOT_SUPPORTED;
3434  }
3435 
3437  SERVICE_QUERY_CONFIG | SERVICE_SET_STATUS );
3438  RtlFreeHeap( GetProcessHeap(), 0, name );
3440 
3441  if (!*service)
3442  {
3443  WARN( "failed to open service %s\n", debugstr_us(service_name) );
3444  return STATUS_UNSUCCESSFUL;
3445  }
3446 
3447  QueryServiceConfigW( *service, NULL, 0, &config_size );
3449  {
3450  WARN( "failed to query service config\n" );
3451  goto error;
3452  }
3453 
3454  if (!(service_config = RtlAllocateHeap( GetProcessHeap(), 0, config_size )))
3455  goto error;
3456 
3457  if (!QueryServiceConfigW( *service, service_config, config_size, &config_size ))
3458  {
3459  WARN( "failed to query service config\n" );
3460  goto error;
3461  }
3462 
3463  if (service_config->dwServiceType != SERVICE_KERNEL_DRIVER &&
3464  service_config->dwServiceType != SERVICE_FILE_SYSTEM_DRIVER)
3465  {
3466  WARN( "service %s is not a kernel driver\n", debugstr_us(service_name) );
3467  goto error;
3468  }
3469 
3470  TRACE( "opened service for driver %s\n", debugstr_us(service_name) );
3471  RtlFreeHeap( GetProcessHeap(), 0, service_config );
3472  return STATUS_SUCCESS;
3473 
3474 error:
3475  CloseServiceHandle( *service );
3476  RtlFreeHeap( GetProcessHeap(), 0, service_config );
3477  return STATUS_UNSUCCESSFUL;
3478 }
3479 
3480 /* find the LDR_DATA_TABLE_ENTRY corresponding to the driver module */
3482 {
3484  ULONG_PTR magic;
3485 
3486  LdrLockLoaderLock( 0, NULL, &magic );
3488  {
3489  WARN( "module not found for %p\n", module );
3490  ldr = NULL;
3491  }
3492  LdrUnlockLoaderLock( 0, magic );
3493 
3494  return ldr;
3495 }
3496 
3497 /* convert PE image VirtualAddress to Real Address */
3498 static inline void *get_rva( HMODULE module, DWORD va )
3499 {
3500  return (void *)((char *)module + va);
3501 }
3502 
3504 {
3505  const IMAGE_DATA_DIRECTORY *relocs;
3506  IMAGE_BASE_RELOCATION *rel, *end;
3509  INT_PTR delta;
3510  char *base;
3511  HMODULE module;
3512 
3514  TRACE( "loading %s\n", debugstr_us(data->Loaded.BaseDllName));
3515 
3516  module = data->Loaded.DllBase;
3517  nt = RtlImageNtHeader( module );
3518  base = (char *)nt->OptionalHeader.ImageBase;
3519  if (!(delta = (char *)module - base)) return;
3520 
3521  /* the loader does not apply relocations to non page-aligned binaries or executables,
3522  * we have to do it ourselves */
3523 
3526  return;
3527 
3529  {
3530  WARN( "Need to relocate module from %p to %p, but there are no relocation records\n", base, module );
3531  return;
3532  }
3533 
3535  if (!relocs->Size || !relocs->VirtualAddress) return;
3536 
3537  TRACE( "relocating from %p-%p to %p-%p\n", base, base + nt->OptionalHeader.SizeOfImage,
3538  module, (char *)module + nt->OptionalHeader.SizeOfImage );
3539 
3540  rel = get_rva( module, relocs->VirtualAddress );
3541  end = get_rva( module, relocs->VirtualAddress + relocs->Size );
3542 
3543  while (rel < end - 1 && rel->SizeOfBlock)
3544  {
3545  char *page = get_rva( module, rel->VirtualAddress );
3546  DWORD old_prot1, old_prot2;
3547 
3549  {
3550  WARN( "invalid address %p in relocation %p\n", get_rva( module, rel->VirtualAddress ), rel );
3551  return;
3552  }
3553 
3554  /* Relocation entries may hang over the end of the page, so we need to
3555  * protect two pages. */
3556  VirtualProtect( page, info.PageSize, PAGE_READWRITE, &old_prot1 );
3557  VirtualProtect( page + info.PageSize, info.PageSize, PAGE_READWRITE, &old_prot2 );
3558  rel = LdrProcessRelocationBlock( page, (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT),
3559  (USHORT *)(rel + 1), delta );
3560  VirtualProtect( page, info.PageSize, old_prot1, &old_prot1 );
3561  VirtualProtect( page + info.PageSize, info.PageSize, old_prot2, &old_prot2 );
3562  if (!rel)
3563  {
3564  WARN( "LdrProcessRelocationBlock failed\n" );
3565  return;
3566  }
3567  }
3568 }
3569 
3570 /* load the .sys module for a device driver */
3571 static HMODULE load_driver( const WCHAR *driver_name, const UNICODE_STRING *keyname )
3572 {
3573  static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0};
3574  static const WCHAR systemrootW[] = {'\\','S','y','s','t','e','m','R','o','o','t','\\',0};
3575  static const WCHAR postfixW[] = {'.','s','y','s',0};
3576  static const WCHAR ntprefixW[] = {'\\','?','?','\\',0};
3577  static const WCHAR ImagePathW[] = {'I','m','a','g','e','P','a','t','h',0};
3578  HKEY driver_hkey;
3579  HMODULE module;
3580  LPWSTR path = NULL, str;
3581  DWORD type, size;
3582 
3583  if (RegOpenKeyW( HKEY_LOCAL_MACHINE, keyname->Buffer + 18 /* skip \registry\machine */, &driver_hkey ))
3584  {
3585  ERR( "cannot open key %s, err=%u\n", wine_dbgstr_w(keyname->Buffer), GetLastError() );
3586  return NULL;
3587  }
3588 
3589  /* read the executable path from memory */
3590  size = 0;
3591  if (!RegQueryValueExW( driver_hkey, ImagePathW, NULL, &type, NULL, &size ))
3592  {
3593  str = HeapAlloc( GetProcessHeap(), 0, size );
3594  if (!RegQueryValueExW( driver_hkey, ImagePathW, NULL, &type, (LPBYTE)str, &size ))
3595  {
3597  path = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
3599  }
3600  HeapFree( GetProcessHeap(), 0, str );
3601  if (!path)
3602  {
3603  RegCloseKey( driver_hkey );
3604  return NULL;
3605  }
3606 
3607  if (!wcsnicmp( path, systemrootW, 12 ))
3608  {
3610 
3612 
3613  str = HeapAlloc(GetProcessHeap(), 0, (size -11 + lstrlenW(buffer))
3614  * sizeof(WCHAR));
3615  lstrcpyW(str, buffer);
3616  lstrcatW(str, path + 11);
3617  HeapFree( GetProcessHeap(), 0, path );
3618  path = str;
3619  }
3620  else if (!wcsncmp( path, ntprefixW, 4 ))
3621  str = path + 4;
3622  else
3623  str = path;
3624  }
3625  else
3626  {
3627  /* default is to use the driver name + ".sys" */
3631  (lstrlenW(buffer) + lstrlenW(driversW) + lstrlenW(driver_name) + lstrlenW(postfixW) + 1)
3632  *sizeof(WCHAR));
3633  lstrcpyW(path, buffer);
3634  lstrcatW(path, driversW);
3635  lstrcatW(path, driver_name);
3636  lstrcatW(path, postfixW);
3637  str = path;
3638  }
3639  RegCloseKey( driver_hkey );
3640 
3641  TRACE( "loading driver %s\n", wine_dbgstr_w(str) );
3642 
3643  module = LoadLibraryW( str );
3644 
3646  {
3647  UNICODE_STRING module_name;
3649  IMAGE_INFO info;
3650  unsigned int i;
3651 
3652  RtlInitUnicodeString(&module_name, str);
3654  memset(&info, 0, sizeof(info));
3655  info.u.s.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
3656  info.u.s.SystemModeImage = TRUE;
3657  info.ImageSize = nt->OptionalHeader.SizeOfImage;
3658  info.ImageBase = module;
3659 
3660  for (i = 0; i < load_image_notify_routine_count; ++i)
3661  {
3662  TRACE("Calling image load notify %p.\n", load_image_notify_routines[i]);
3663  load_image_notify_routines[i](&module_name, NULL, &info);
3664  TRACE("Called image load notify %p.\n", load_image_notify_routines[i]);
3665  }
3666  }
3667 
3668  HeapFree( GetProcessHeap(), 0, path );
3669  return module;
3670 }
3671 
3672 /* call the driver init entry point */
3673 static NTSTATUS WINAPI init_driver( DRIVER_OBJECT *driver_object, UNICODE_STRING *keyname )
3674 {
3675  unsigned int i;
3676  NTSTATUS status;
3677  const IMAGE_NT_HEADERS *nt;
3678  const WCHAR *driver_name;
3679  HMODULE module;
3680 
3681  /* Retrieve driver name from the keyname */
3682  driver_name = wcsrchr( keyname->Buffer, '\\' );
3683  driver_name++;
3684 
3685  module = load_driver( driver_name, keyname );
3686  if (!module)
3687  return STATUS_DLL_INIT_FAILED;
3688 
3689  driver_object->DriverSection = find_ldr_module( module );
3690  driver_object->DriverStart = ((LDR_DATA_TABLE_ENTRY *)driver_object->DriverSection)->DllBase;
3691  driver_object->DriverSize = ((LDR_DATA_TABLE_ENTRY *)driver_object->DriverSection)->SizeOfImage;
3692 
3693  nt = RtlImageNtHeader( module );
3696 
3697  TRACE_(relay)( "\1Call driver init %p (obj=%p,str=%s)\n",
3698  driver_object->DriverInit, driver_object, wine_dbgstr_w(keyname->Buffer) );
3699 
3700  status = driver_object->DriverInit( driver_object, keyname );
3701 
3702  TRACE_(relay)( "\1Ret driver init %p (obj=%p,str=%s) retval=%08x\n",
3703  driver_object->DriverInit, driver_object, wine_dbgstr_w(keyname->Buffer), status );
3704 
3705  TRACE( "init done for %s obj %p\n", wine_dbgstr_w(driver_name), driver_object );
3706  TRACE( "- DriverInit = %p\n", driver_object->DriverInit );
3707  TRACE( "- DriverStartIo = %p\n", driver_object->DriverStartIo );
3708  TRACE( "- DriverUnload = %p\n", driver_object->DriverUnload );
3709  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
3710  TRACE( "- MajorFunction[%d] = %p\n", i, driver_object->MajorFunction[i] );
3711 
3712  return status;
3713 }
3714 
3715 static BOOLEAN get_drv_name( UNICODE_STRING *drv_name, const UNICODE_STRING *service_name )
3716 {
3717  static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0};
3718  WCHAR *str;
3719 
3720  if (!(str = heap_alloc( sizeof(driverW) + service_name->Length - lstrlenW(servicesW)*sizeof(WCHAR) )))
3721  return FALSE;
3722 
3723  lstrcpyW( str, driverW );
3724  lstrcpynW( str + lstrlenW(driverW), service_name->Buffer + lstrlenW(servicesW),
3725  service_name->Length/sizeof(WCHAR) - lstrlenW(servicesW) + 1 );
3726  RtlInitUnicodeString( drv_name, str );
3727  return TRUE;
3728 }
3729 
3730 /***********************************************************************
3731  * ZwLoadDriver (NTOSKRNL.EXE.@)
3732  */
3734 {
3735  SERVICE_STATUS_HANDLE service_handle;
3736  struct wine_rb_entry *entry;
3737  struct wine_driver *driver;
3738  UNICODE_STRING drv_name;
3739  NTSTATUS status;
3740 
3741  TRACE( "(%s)\n", debugstr_us(service_name) );
3742 
3743  if ((status = open_driver( service_name, (SC_HANDLE *)&service_handle )) != STATUS_SUCCESS)
3744  return status;
3745 
3746  if (!get_drv_name( &drv_name, service_name ))
3747  {
3749  return STATUS_NO_MEMORY;
3750  }
3751 
3752  if (wine_rb_get( &wine_drivers, &drv_name ))
3753  {
3754  TRACE( "driver %s already loaded\n", debugstr_us(&drv_name) );
3755  RtlFreeUnicodeString( &drv_name );
3758  }
3759 
3761 
3762  status = IoCreateDriver( &drv_name, init_driver );
3763  entry = wine_rb_get( &wine_drivers, &drv_name );
3764  RtlFreeUnicodeString( &drv_name );
3765  if (status != STATUS_SUCCESS)
3766  {
3767  ERR( "failed to create driver %s: %08x\n", debugstr_us(service_name), status );
3768  goto error;
3769  }
3770 
3772  driver->service_handle = service_handle;
3773 
3775 
3778  return STATUS_SUCCESS;
3779 
3780 error:
3783  return status;
3784 }
3785 
3786 /***********************************************************************
3787  * ZwUnloadDriver (NTOSKRNL.EXE.@)
3788  */
3790 {
3791  struct wine_rb_entry *entry;
3792  UNICODE_STRING drv_name;
3793 
3794  TRACE( "(%s)\n", debugstr_us(service_name) );
3795 
3796  if (!get_drv_name( &drv_name, service_name ))
3797  return STATUS_NO_MEMORY;
3798 
3799  entry = wine_rb_get( &wine_drivers, &drv_name );
3800  RtlFreeUnicodeString( &drv_name );
3801  if (!entry)
3802  {
3803  ERR( "failed to locate driver %s\n", debugstr_us(service_name) );
3805  }
3806 
3807  unload_driver( entry, NULL );
3808 
3809  return STATUS_SUCCESS;
3810 }
3811 
3812 /***********************************************************************
3813  * IoCreateFile (NTOSKRNL.EXE.@)
3814  */
3816  IO_STATUS_BLOCK *io, LARGE_INTEGER *alloc_size, ULONG attributes, ULONG sharing,
3817  ULONG disposition, ULONG create_options, VOID *ea_buffer, ULONG ea_length,
3818  CREATE_FILE_TYPE file_type, VOID *parameters, ULONG options )
3819 {
3820  FIXME(": stub\n");
3821  return STATUS_NOT_IMPLEMENTED;
3822 }
3823 
3824 /***********************************************************************
3825  * IoCreateNotificationEvent (NTOSKRNL.EXE.@)
3826  */
3828 {
3829  FIXME( "stub: %s %p\n", debugstr_us(name), handle );
3830  return NULL;
3831 }
3832 
3833 
3834 /**************************************************************************
3835  * __chkstk (NTOSKRNL.@)
3836  */
3837 #ifdef __x86_64__
3838 /* Supposed to touch all the stack pages, but we shouldn't need that. */
3839 __ASM_GLOBAL_FUNC( __chkstk, "ret" );
3840 #elif defined(__i386__)
3841 __ASM_GLOBAL_FUNC( _chkstk,
3842  "negl %eax\n\t"
3843  "addl %esp,%eax\n\t"
3844  "xchgl %esp,%eax\n\t"
3845  "movl 0(%eax),%eax\n\t" /* copy return address from old location */
3846  "movl %eax,0(%esp)\n\t"
3847  "ret" )
3848 #elif defined(__arm__)
3849 /* Incoming r4 contains words to allocate, converting to bytes then return */
3850 __ASM_GLOBAL_FUNC( __chkstk, "lsl r4, r4, #2\n\t"
3851  "bx lr" )
3852 #elif defined(__aarch64__)
3853 /* Supposed to touch all the stack pages, but we shouldn't need that. */
3854 __ASM_GLOBAL_FUNC( __chkstk, "ret" );
3855 #endif
3856 
3857 /*********************************************************************
3858  * PsAcquireProcessExitSynchronization (NTOSKRNL.@)
3859 */
3861 {
3862  FIXME("stub: %p\n", process);
3863 
3864  return STATUS_NOT_IMPLEMENTED;
3865 }
3866 
3867 /*********************************************************************
3868  * PsReleaseProcessExitSynchronization (NTOSKRNL.@)
3869  */
3871 {
3872  FIXME("stub: %p\n", process);
3873 }
3874 
3875 typedef struct _EX_PUSH_LOCK_WAIT_BLOCK *PEX_PUSH_LOCK_WAIT_BLOCK;
3876 /*********************************************************************
3877  * ExfUnblockPushLock (NTOSKRNL.@)
3878  */
3881 {
3882  FIXME( "stub: %p, %p\n", lock, block );
3883 }
3884 
3885 /*********************************************************************
3886  * FsRtlRegisterFileSystemFilterCallbacks (NTOSKRNL.@)
3887  */
3889 {
3890  FIXME("stub: %p %p\n", object, callbacks);
3891  return STATUS_NOT_IMPLEMENTED;
3892 }
3893 
3894 /*********************************************************************
3895  * SeSinglePrivilegeCheck (NTOSKRNL.@)
3896  */
3898 {
3899  static int once;
3900  if (!once++) FIXME("stub: %08x%08x %u\n", privilege.HighPart, privilege.LowPart, mode);
3901  return TRUE;
3902 }
3903 
3904 /*********************************************************************
3905  * SePrivilegeCheck (NTOSKRNL.@)
3906  */
3908 {
3909  FIXME("stub: %p %p %u\n", privileges, context, mode);
3910  return TRUE;
3911 }
3912 
3913 /*********************************************************************
3914  * SeLocateProcessImageName (NTOSKRNL.@)
3915  */
3917 {
3918  FIXME("stub: %p %p\n", process, image_name);
3919  if (image_name) *image_name = NULL;
3920  return STATUS_NOT_IMPLEMENTED;
3921 }
3922 
3923 /*********************************************************************
3924  * KeFlushQueuedDpcs (NTOSKRNL.@)
3925  */
3927 {
3928  FIXME("stub!\n");
3929 }
3930 
3931 /*********************************************************************
3932  * DbgQueryDebugFilterState (NTOSKRNL.@)
3933  */
3935 {
3936  FIXME("stub: %d %d\n", component, level);
3937  return STATUS_NOT_IMPLEMENTED;
3938 }
3939 
3940 /*********************************************************************
3941  * PsGetProcessWow64Process (NTOSKRNL.@)
3942  */
3944 {
3945  FIXME("stub: %p\n", process);
3946  return NULL;
3947 }
3948 
3949 /*********************************************************************
3950  * MmCopyVirtualMemory (NTOSKRNL.@)
3951  */
3952 NTSTATUS WINAPI MmCopyVirtualMemory(PEPROCESS fromprocess, void *fromaddress, PEPROCESS toprocess,
3953  void *toaddress, SIZE_T bufsize, KPROCESSOR_MODE mode,
3954  SIZE_T *copied)
3955 {
3956  FIXME("fromprocess %p, fromaddress %p, toprocess %p, toaddress %p, bufsize %lu, mode %d, copied %p stub.\n",
3957  fromprocess, fromaddress, toprocess, toaddress, bufsize, mode, copied);
3958 
3959  *copied = 0;
3960  return STATUS_NOT_IMPLEMENTED;
3961 }
3962 
3963 /*********************************************************************
3964  * KeEnterGuardedRegion (NTOSKRNL.@)
3965  */
3967 {
3968  FIXME("\n");
3969 }
3970 
3971 /*********************************************************************
3972  * KeLeaveGuardedRegion (NTOSKRNL.@)
3973  */
3975 {
3976  FIXME("\n");
3977 }
3978 
3979 static const WCHAR token_type_name[] = {'T','o','k','e','n',0};
3980 
3981 static struct _OBJECT_TYPE token_type =
3982 {
3984 };
3985 
3987 
3988 /*************************************************************************
3989  * ExUuidCreate (NTOSKRNL.@)
3990  *
3991  * Creates a 128bit UUID.
3992  *
3993  * RETURNS
3994  *
3995  * STATUS_SUCCESS if successful.
3996  * RPC_NT_UUID_LOCAL_ONLY if UUID is only locally unique.
3997  *
3998  * NOTES
3999  *
4000  * Follows RFC 4122, section 4.4 (Algorithms for Creating a UUID from
4001  * Truly Random or Pseudo-Random Numbers)
4002  */
4004 {
4005  RtlGenRandom(uuid, sizeof(*uuid));
4006  /* Clear the version bits and set the version (4) */
4007  uuid->Data3 &= 0x0fff;
4008  uuid->Data3 |= (4 << 12);
4009  /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as
4010  * specified in RFC 4122, section 4.4.
4011  */
4012  uuid->Data4[0] &= 0x3f;
4013  uuid->Data4[0] |= 0x80;
4014 
4015  TRACE("%s\n", debugstr_guid(uuid));
4016 
4017  return STATUS_SUCCESS;
4018 }
4019 
4020 /***********************************************************************
4021  * ExSetTimerResolution (NTOSKRNL.EXE.@)
4022  */
4024 {
4025  FIXME("stub: %u %d\n", time, set_resolution);
4026  return KeQueryTimeIncrement();
4027 }
4028 
4029 /***********************************************************************
4030  * IoGetRequestorProcess (NTOSKRNL.EXE.@)
4031  */
4033 {
4034  TRACE("irp %p.\n", irp);
4035  return irp->Tail.Overlay.Thread->kthread.process;
4036 }
4037 
4038 #ifdef _WIN64
4039 /***********************************************************************
4040  * IoIs32bitProcess (NTOSKRNL.EXE.@)
4041  */
4042 BOOLEAN WINAPI IoIs32bitProcess(IRP *irp)
4043 {
4044  TRACE("irp %p.\n", irp);
4045  return irp->Tail.Overlay.Thread->kthread.process->wow64;
4046 }
4047 #endif
4048 
4049 /***********************************************************************
4050  * RtlIsNtDdiVersionAvailable (NTOSKRNL.EXE.@)
4051  */
4053 {
4054  FIXME("stub: %d\n", version);
4055  return FALSE;
4056 }
4057 
4059 {
4060  TRACE(".\n");
4061 
4062  return !KdDebuggerEnabled;
4063 }
4064 
4066 {
4068  PKDEFERRED_ROUTINE routine;
4070  void *context;
4074 };
4075 
4077 {
4078  struct generic_call_dpc_context *c = context;
4079  GROUP_AFFINITY old, new;
4080 
4081  TRACE("instance %p, context %p.\n", instance, context);
4082 
4084  &old, sizeof(old), NULL);
4085 
4086  memset(&new, 0, sizeof(new));
4087 
4088  new.Mask = 1 << c->cpu_index;
4090 
4092  c->routine((PKDPC)0xdeadbeef, c->context, c->cpu_count_barrier, c->reverse_barrier);
4095 }
4096 
4097 void WINAPI KeGenericCallDpc(PKDEFERRED_ROUTINE routine, void *context)
4098 {
4100  static struct generic_call_dpc_context *contexts;
4102  static ULONG last_cpu_count;
4105  ULONG i;
4106 
4107  TRACE("routine %p, context %p.\n", routine, context);
4108 
4110 
4111  if (!dpc_call_tp)
4112  {
4113  if (!(dpc_call_tp = CreateThreadpool(NULL)))
4114  {
4115  ERR("Could not create thread pool.\n");
4117  return;
4118  }
4119 
4122 
4123  memset(&dpc_call_tpe, 0, sizeof(dpc_call_tpe));
4124  dpc_call_tpe.Version = 1;
4126  }
4127 
4128  reverse_barrier.Barrier = cpu_count;
4129  reverse_barrier.TotalProcessors = cpu_count;
4130  cpu_count_barrier = cpu_count;
4131 
4132  if (contexts)
4133  {
4134  if (last_cpu_count < cpu_count)
4135  {
4136  static struct generic_call_dpc_context *new_contexts;
4137  if (!(new_contexts = heap_realloc(contexts, sizeof(*contexts) * cpu_count)))
4138  {
4139  ERR("No memory.\n");
4141  return;
4142  }
4143  contexts = new_contexts;
4146  }
4147  }
4148  else if (!(contexts = heap_alloc(sizeof(*contexts) * cpu_count)))
4149  {
4150  ERR("No memory.\n");
4152  return;
4153  }
4154 
4155  memset(contexts, 0, sizeof(*contexts) * cpu_count);
4156  last_cpu_count = cpu_count;
4158 
4159  for (i = 0; i < cpu_count; ++i)
4160  {
4161  contexts[i].reverse_barrier = &reverse_barrier;
4162  contexts[i].cpu_count_barrier = &cpu_count_barrier;
4163  contexts[i].routine = routine;
4164  contexts[i].context = context;
4165  contexts[i].cpu_index = i;
4167 
4169  }
4170 
4171  while (InterlockedCompareExchange((LONG *)&cpu_count_barrier, 0, 0))
4172  SwitchToThread();
4173 
4175 }
4176 
4177 
4179 {
4181  DEFERRED_REVERSE_BARRIER *b = barrier;
4182  LONG curr_flag, comp, done_value;
4183  BOOL first;
4184 
4185  TRACE("barrier %p, context %p.\n", barrier, context);
4186 
4187  if (!context)
4188  {
4189  WARN("Called outside of DPC context.\n");
4190  return FALSE;
4191  }
4192 
4193  context->current_barrier_flag ^= 0x80000000;
4194  curr_flag = context->current_barrier_flag;
4195 
4196  first = !context->cpu_index;
4197  comp = curr_flag + context->cpu_index;
4198  done_value = curr_flag + b->TotalProcessors;
4199 
4200  if (first)
4201  InterlockedExchange((LONG *)&b->Barrier, comp);
4202 
4203  while (InterlockedCompareExchange((LONG *)&b->Barrier, comp + 1, comp) != done_value)
4204  ;
4205 
4206  InterlockedIncrement(context->barrier_passed_count);
4207 
4208  while (first && InterlockedCompareExchange(context->barrier_passed_count, 0, b->TotalProcessors))
4209  ;
4210 
4211  return first;
4212 }
4213 
4214 void WINAPI KeSignalCallDpcDone(void *barrier)
4215 {
4216  InterlockedDecrement((LONG *)barrier);
4217 }
4218 
4220 {
4221  void *image_base;
4222  NTSTATUS status;
4223  SIZE_T size;
4224  HANDLE h;
4225 
4226  TRACE("process %p.\n", process);
4227 
4229  {
4230  WARN("Error opening process object, status %#x.\n", status);
4231  return NULL;
4232  }
4233 
4234  status = NtReadVirtualMemory(h, &process->info.PebBaseAddress->ImageBaseAddress,
4235  &image_base, sizeof(image_base), &size);
4236 
4237  NtClose(h);
4238 
4239  if (status || size != sizeof(image_base))
4240  {
4241  WARN("Error reading process memory, status %#x, size %lu.\n", status, size);
4242  return NULL;
4243  }
4244 
4245  TRACE("returning %p.\n", image_base);
4246  return image_base;
4247 }
4248 
4250 {
4251  FIXME("process %p, apc_state %p stub.\n", process, apc_state);
4252 }
4253 
4255 {
4256  FIXME("apc_state %p stub.\n", apc_state);
4257 }
4258 
4260 {
4261  FIXME(": stub.\n");
4262  return STATUS_DEBUGGER_INACTIVE;
4263 }
4264 
4266 {
4267  FIXME(": stub.\n");
4268  return STATUS_DEBUGGER_INACTIVE;
4269 }
4270 
4271 /*****************************************************
4272  * DllMain
4273  */
4275 {
4276  static void *handler;
4277  LARGE_INTEGER count;
4278 
4279  switch(reason)
4280  {
4281  case DLL_PROCESS_ATTACH:
4283 #if defined(__i386__) || defined(__x86_64__)
4285 #endif
4286  KeQueryTickCount( &count ); /* initialize the global KeTickCount */
4287  NtBuildNumber = NtCurrentTeb()->Peb->OSBuildNumber;
4291  break;
4292  case DLL_PROCESS_DETACH:
4294 
4295  if (reserved) break;
4296 
4297  if (dpc_call_tp)
4299 
4302  break;
4303  }
4304  return TRUE;
4305 }
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7432
static LPCSTR debugstr_us(const UNICODE_STRING *us)
Definition: lsa.c:47
#define DEFINE_FASTCALL1_WRAPPER(func)
Definition: asm.h:136
#define DEFINE_FASTCALL_WRAPPER(func, args)
Definition: asm.h:137
#define __ASM_GLOBAL_FUNC(name, code)
Definition: asm.h:90
static const WCHAR version[]
Definition: asmname.c:63
#define assert(_expr)
Definition: assert.h:32
ULONG_PTR KAFFINITY
Definition: basetsd.h:266
ULONG_PTR DWORD_PTR
Definition: basetsd.h:131
#define UlongToHandle(ul)
Definition: basetsd.h:259
#define HandleToUlong(h)
Definition: basetsd.h:258
unsigned long ULONG_PTR
Definition: basetsd.h:130
unsigned long * PULONG_PTR
Definition: basetsd.h:130
long INT_PTR
Definition: basetsd.h:127
ULONG_PTR SIZE_T
Definition: basetsd.h:264
LONG NTSTATUS
Definition: bcrypt.h:40
#define WINAPI
Definition: bcrypt.h:23
unsigned char major
enum shader_type type
unsigned char minor
Definition: type.pm:7
#define ERR(...)
Definition: cocoa_app.h:61
static int WINAPIV swprintf(wchar_t *buffer, size_t size, const wchar_t *format,...)
PIRP(WINAPI * PIO_CSQ_PEEK_NEXT_IRP)(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext)
Definition: csq.h:28
void(WINAPI * PIO_CSQ_INSERT_IRP)(struct _IO_CSQ *Csq, PIRP Irp)
Definition: csq.h:27
void(WINAPI * PIO_CSQ_ACQUIRE_LOCK)(PIO_CSQ Csq, PKIRQL Irql)
Definition: csq.h:25
struct _IO_CSQ * PIO_CSQ
Definition: csq.h:24
void(WINAPI * PIO_CSQ_COMPLETE_CANCELED_IRP)(PIO_CSQ Csq, PIRP Irp)
Definition: csq.h:26
void(WINAPI * PIO_CSQ_REMOVE_IRP)(PIO_CSQ Csq, PIRP Irp)
Definition: csq.h:30
void(WINAPI * PIO_CSQ_RELEASE_LOCK)(PIO_CSQ Csq, KIRQL Irql)
Definition: csq.h:29
device_type
static void delete_device(struct device *device)
Definition: devinst.c:725
static HRESULT create_device(IDirectInputImpl *This, const GUID *const rguid, const IID *const riid, LPVOID *pvOut, BOOL unicode)
Definition: dinput_main.c:853
LSTATUS RegOpenKeyW(HKEY hkey, LPCWSTR name, PHKEY retkey)
Definition: registry.c:121
static HINSTANCE instance
Definition: main.c:40
static WCHAR reason[128]
Definition: object.c:1941
int id
Definition: main.c:4907
static HANDLE stop_event
Definition: main.c:30
static SERVICE_STATUS_HANDLE service_handle
Definition: main.c:29
BOOL GetProcessAffinityMask(HANDLE hProcess, PDWORD_PTR process_mask, PDWORD_PTR system_mask)
Definition: process.c:327
void ExitProcess(DWORD status)
Definition: process.c:204
DWORD GetActiveProcessorCount(WORD group)
Definition: process.c:610
UINT GetWindowsDirectoryW(LPWSTR path, UINT count)
Definition: file.c:2406
BOOL DisableThreadLibraryCalls(HMODULE module)
Definition: loader.c:222
HMODULE GetModuleHandleW(LPCWSTR module)
Definition: loader.c:352
HMODULE LoadLibraryW(LPCWSTR name)
Definition: loader.c:490
BOOL FreeLibrary(HINSTANCE module)
Definition: loader.c:231
BOOL VirtualFree(void *addr, SIZE_T size, DWORD type)
Definition: memory.c:320
LPVOID VirtualAlloc(void *addr, SIZE_T size, DWORD type, DWORD protect)
Definition: memory.c:283
BOOL VirtualProtect(void *addr, SIZE_T size, DWORD new_prot, DWORD *old_prot)
Definition: memory.c:347
HANDLE OpenProcess(DWORD access, BOOL inherit, DWORD id)
Definition: process.c:1020
DWORD ExpandEnvironmentStringsW(LPCWSTR src, LPWSTR dst, DWORD len)
Definition: process.c:1374
BOOL IsWow64Process(HANDLE process, PBOOL wow64)
Definition: process.c:1006
LSTATUS RegQueryValueExW(HKEY hkey, LPCWSTR name, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
Definition: registry.c:1424
LSTATUS RegCloseKey(HKEY hkey)
Definition: registry.c:964
BOOL SwitchToThread(void)
Definition: thread.c:624
HANDLE OpenThread(DWORD access, BOOL inherit, DWORD id)
Definition: thread.c:345
BOOL TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1206
BOOL TlsSetValue(DWORD index, LPVOID value)
Definition: thread.c:723
DWORD TlsAlloc(void)
Definition: thread.c:642
PTP_POOL CreateThreadpool(void *reserved)
Definition: thread.c:1123
LPVOID TlsGetValue(DWORD index)
Definition: thread.c:704
int remove(const char *path)
Definition: file.c:4819
void * memcpy(void *dst, const void *src, size_t n)
Definition: string.c:2580
void * memset(void *dst, int c, size_t n)
Definition: string.c:2588
void * memmove(void *dst, const void *src, size_t n)
Definition: string.c:2481
IMAGE_BASE_RELOCATION * LdrProcessRelocationBlock(void *page, UINT count, USHORT *relocs, INT_PTR delta)
Definition: loader.c:2865
NTSTATUS LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FUNCTION callback, void *context, void **cookie)
Definition: loader.c:1610
NTSTATUS LdrUnregisterDllNotification(void *cookie)
Definition: loader.c:1639
NTSTATUS LdrUnlockLoaderLock(ULONG flags, ULONG_PTR magic)
Definition: loader.c:1693
static PEB_LDR_DATA ldr
Definition: loader.c:159
NTSTATUS LdrFindEntryForAddress(const void *addr, PLDR_DATA_TABLE_ENTRY *pmod)
Definition: loader.c:1560
PIMAGE_NT_HEADERS RtlImageNtHeader(HMODULE hModule)
Definition: loader.c:3395
NTSTATUS LdrLockLoaderLock(ULONG flags, ULONG *result, ULONG_PTR *magic)
Definition: loader.c:1661
NTSTATUS RtlCreateUserThread(HANDLE process, SECURITY_DESCRIPTOR *descr, BOOLEAN suspended, PVOID stack_addr, SIZE_T stack_reserve, SIZE_T stack_commit, PRTL_THREAD_START_ROUTINE start, void *param, HANDLE *handle_ptr, CLIENT_ID *id)
Definition: thread.c:154
NTSTATUS NtQueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS info_class, void *ptr, ULONG len, ULONG *used_len)
Definition: file.c:6497
const WCHAR * source
Definition: file.c:2624
NTSTATUS NtQueryInformationProcess(HANDLE handle, PROCESSINFOCLASS class, void *info, ULONG size, ULONG *ret_len)
Definition: process.c:1178
NTSTATUS NtClose(HANDLE handle)
Definition: server.c:1666
unsigned int wine_server_call(void *req_ptr)
Definition: server.c:283
NTSTATUS NtOpenThread(HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id)
Definition: thread.c:451
NTSTATUS NtSetInformationThread(HANDLE handle, THREADINFOCLASS class, const void *data, ULONG length)
Definition: thread.c:1162
NTSTATUS NtQueryInformationThread(HANDLE handle, THREADINFOCLASS class, void *data, ULONG length, ULONG *ret_len)
Definition: thread.c:897
BOOL QueryServiceConfigW(SC_HANDLE service, QUERY_SERVICE_CONFIGW *ret_config, DWORD size, DWORD *ret_size)
Definition: service.c:707
BOOL SetServiceStatus(SERVICE_STATUS_HANDLE service, SERVICE_STATUS *status)
Definition: service.c:1491
BOOL CloseServiceHandle(SC_HANDLE handle)
Definition: service.c:452
SC_HANDLE OpenServiceW(SC_HANDLE manager, const WCHAR *name, DWORD access)
Definition: service.c:314
SC_HANDLE OpenSCManagerW(const WCHAR *machine, const WCHAR *database, DWORD access)
Definition: service.c:273
static HANDLE thread
Definition: device.c:52
long BOOL
Definition: dxgitype.idl:24
static const size_t stack_size
Definition: engine.c:57
NTSTATUS status
Definition: except.c:81
const char * str
Definition: glu.c:32
#define complete_irp
Definition: http.c:265
static DEVICE_OBJECT * device_obj
Definition: http.c:32
#define DECLARE_CRITICAL_SECTION(cs)
Definition: http.c:36
static const char * wine_dbgstr_w(const WCHAR *s)
Definition: debug.h:316
#define WINE_DECLARE_DEBUG_CHANNEL(ch)
Definition: debug.h:497
static const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: debug.h:344
#define WINE_DEFAULT_DEBUG_CHANNEL(ch)
Definition: debug.h:499
static HINF handles[16384]
Definition: infparse.c:48
Definition: msctf.idl:511
static int access(const char *path, int mode)
Definition: io.h:110
BYTE flags
Definition: ioports.c:48
BOOL HeapDestroy(HANDLE heap)
Definition: heap.c:130
HANDLE HeapCreate(DWORD flags, SIZE_T initialSize, SIZE_T maxSize)
Definition: heap.c:99
FARPROC GetProcAddress(HMODULE hModule, LPCSTR function)
Definition: module.c:348
UINT GetSystemDirectoryW(LPWSTR path, UINT count)
Definition: path.c:235
LPWSTR lstrcatW(LPWSTR dst, LPCWSTR src)
Definition: virtual.c:277
LPWSTR lstrcpyW(LPWSTR dst, LPCWSTR src)
Definition: virtual.c:317
BOOL IsBadReadPtr(LPCVOID ptr, UINT_PTR size)
Definition: virtual.c:74
DWORD WaitForMultipleObjectsEx(DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout, BOOL alertable)
Definition: sync.c:327
DWORD GetVersion(void)
Definition: version.c:1421
GUID guid
Definition: version.c:141
struct version_info info
Definition: version.c:140
#define HeapReAlloc(heap, flags, ptr, size)
Definition: kernelbase.h:54
const IMAGE_NT_HEADERS * nt
Definition: loader.c:73
unsigned int flag
Definition: makedep.c:115
#define min(a, b)
Definition: minmax.h:28
int k
Definition: mpi.c:3366
static void size_t len
basic_istream_char obj
Definition: ios.c:13778
file_type
Definition: ios.c:334
void free(void *ptr)
Definition: heap.c:412
enum _IO_NOTIFICATION_EVENT_CATEGORY IO_NOTIFICATION_EVENT_CATEGORY
void(WINAPI * PLOAD_IMAGE_NOTIFY_ROUTINE)(PUNICODE_STRING, HANDLE, PIMAGE_INFO)
Definition: ntddk.h:237
void(WINAPI * PCREATE_PROCESS_NOTIFY_ROUTINE_EX)(PEPROCESS, HANDLE, PS_CREATE_NOTIFY_INFO *)
Definition: ntddk.h:233
void(WINAPI * PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE, HANDLE, BOOLEAN)
Definition: ntddk.h:232
void(WINAPI * PCREATE_THREAD_NOTIFY_ROUTINE)(HANDLE, HANDLE, BOOLEAN)
Definition: ntddk.h:234
void(WINAPI * PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)(PVOID, PVOID)
Definition: ntddk.h:235
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: ntddk.h:110
void * buffer
Definition: ntddk.h:198
void(WINAPI * PDRIVER_REINITIALIZE)(PDRIVER_OBJECT, PVOID, ULONG)
Definition: ntddk.h:236
EXPAND_STACK_CALLOUT * PEXPAND_STACK_CALLOUT
Definition: ntddk.h:241
NTSTATUS(WINAPI * PIO_QUERY_DEVICE_ROUTINE)(PVOID, PUNICODE_STRING, INTERFACE_TYPE, ULONG, PKEY_VALUE_FULL_INFORMATION *, CONFIGURATION_TYPE, ULONG, PKEY_VALUE_FULL_INFORMATION *)
Definition: ntddk.h:238
enum _CONFIGURATION_TYPE * PCONFIGURATION_TYPE
#define NT_ERROR(status)
Definition: ntdef.h:51
ULONG end
Definition: error.c:1729
ULONG offset
Definition: error.c:1729
ULONG RtlRemoveVectoredExceptionHandler(PVOID handler)
Definition: exception.c:222
PVOID RtlAddVectoredExceptionHandler(ULONG first, PVECTORED_EXCEPTION_HANDLER func)
Definition: exception.c:213
void * RtlAllocateHeap(HANDLE heap, ULONG flags, SIZE_T size)
Definition: heap.c:1652
BOOLEAN RtlFreeHeap(HANDLE heap, ULONG flags, void *ptr)
Definition: heap.c:1737
LONG RtlCompareUnicodeStrings(const WCHAR *s1, SIZE_T len1, const WCHAR *s2, SIZE_T len2, BOOLEAN case_insensitive)
Definition: locale.c:857
ULONG NtGetTickCount(void)
Definition: time.c:400
USHORT * data
Definition: env.c:81
NTSTATUS NtMakeTemporaryObject(HANDLE handle)
Definition: sync.c:1093
NTSTATUS NtCreateSymbolicLinkObject(HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr, UNICODE_STRING *target)
Definition: sync.c:1011
NTSTATUS NtOpenSymbolicLinkObject(HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr)
Definition: sync.c:1040
NTSTATUS NtQuerySystemTime(LARGE_INTEGER *time)
Definition: sync.c:1374
NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS class, void *info, ULONG size, ULONG *ret_size)
Definition: system.c:2062
NTSTATUS NtReadVirtualMemory(HANDLE process, const void *addr, void *buffer, SIZE_T size, SIZE_T *bytes_read)
Definition: virtual.c:4303
NTSTATUS RtlGetVersion(RTL_OSVERSIONINFOEXW *info)
Definition: version.c:533
struct _EX_PUSH_LOCK EX_PUSH_LOCK
Definition: ntifs.h:24
void KeQueryTickCount(LARGE_INTEGER *count)
Definition: ntoskrnl.c:2462
static struct _OBJECT_TYPE driver_type
Definition: ntoskrnl.c:1402
void IoCompleteRequest(IRP *irp, UCHAR priority_boost)
Definition: ntoskrnl.c:1901
void ObUnRegisterCallbacks(void *handle)
Definition: ntoskrnl.c:2889
NTSTATUS PsRemoveLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine)
Definition: ntoskrnl.c:3046
static void * create_thread_object(HANDLE handle)
Definition: ntoskrnl.c:2299
static struct _OBJECT_TYPE token_type
Definition: ntoskrnl.c:3981
LONG KeInsertQueue(PRKQUEUE Queue, PLIST_ENTRY Entry)
Definition: ntoskrnl.c:2405
static NTSTATUS open_driver(const UNICODE_STRING *service_name, SC_HANDLE *service)
Definition: ntoskrnl.c:3409
NTSTATUS IoIsWdmVersionAvailable(UCHAR MajorVersion, UCHAR MinorVersion)
Definition: ntoskrnl.c:1762
void ExFreePool(void *ptr)
Definition: ntoskrnl.c:2103
void * ExRegisterCallback(PCALLBACK_OBJECT callback_object, PCALLBACK_FUNCTION callback_function, void *callback_context)
Definition: ntoskrnl.c:2086
static NTSTATUS dispatch_irp_completion(DEVICE_OBJECT *device, IRP *irp, void *context)
Definition: ntoskrnl.c:438
POBJECT_TYPE IoDriverObjectType
Definition: ntoskrnl.c:1409
void ObfReferenceObject(void *obj)
Definition: ntoskrnl.c:2858
void KeFlushQueuedDpcs(void)
Definition: ntoskrnl.c:3926
DEVICE_OBJECT * IoGetAttachedDevice(DEVICE_OBJECT *device)
Definition: ntoskrnl.c:1193
PVOID MmMapIoSpace(PHYSICAL_ADDRESS PhysicalAddress, DWORD NumberOfBytes, DWORD CacheType)
Definition: ntoskrnl.c:2676
NTSTATUS IoGetDeviceObjectPointer(UNICODE_STRING *name, ACCESS_MASK access, PFILE_OBJECT *file, PDEVICE_OBJECT *device)
Definition: ntoskrnl.c:1673
static const POBJECT_TYPE * known_types[]
Definition: ntoskrnl.c:259
NTSTATUS IoQueryDeviceDescription(PINTERFACE_TYPE itype, PULONG bus, PCONFIGURATION_TYPE ctype, PULONG cnum, PCONFIGURATION_TYPE ptype, PULONG pnum, PIO_QUERY_DEVICE_ROUTINE callout, PVOID context)
Definition: ntoskrnl.c:1827
void PsRevertToSelf(void)
Definition: ntoskrnl.c:2997
static void ldr_notify_callback(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: ntoskrnl.c:3503
static void cancel_completed_irp(DEVICE_OBJECT *device, IRP *irp)
Definition: ntoskrnl.c:426
NTSTATUS IoCreateDevice(DRIVER_OBJECT *driver, ULONG ext_size, UNICODE_STRING *name, DWORD type, ULONG characteristics, BOOLEAN exclusive, DEVICE_OBJECT **ret_device)
Definition: ntoskrnl.c:1490
static NTSTATUS dispatch_write(struct dispatch_context *context)
Definition: ntoskrnl.c:635
static DWORD request_thread
Definition: ntoskrnl.c:81
PVOID MmMapLockedPagesSpecifyCache(PMDLX MemoryDescriptorList, KPROCESSOR_MODE AccessMode, MEMORY_CACHING_TYPE CacheType, PVOID BaseAddress, ULONG BugCheckOnFailure, MM_PAGE_PRIORITY Priority)
Definition: ntoskrnl.c:2694
void ObDereferenceObject(void *obj)
Definition: ntoskrnl.c:185
static void * create_process_object(HANDLE handle)
Definition: ntoskrnl.c:2229
BOOLEAN PsIsSystemThread(PETHREAD thread)
Definition: ntoskrnl.c:2950
void * alloc_kernel_object(POBJECT_TYPE type, HANDLE handle, SIZE_T size, LONG ref)
Definition: ntoskrnl.c:154
POBJECT_TYPE IoDeviceObjectType
Definition: ntoskrnl.c:1484
void KeSetTargetProcessorDpc(PRKDPC dpc, CCHAR number)
Definition: ntoskrnl.c:3189
static struct wine_rb_tree wine_drivers
Definition: ntoskrnl.c:109
NTSTATUS PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE routine)
Definition: ntoskrnl.c:3223
void KeEnterCriticalRegion(void)
Definition: ntoskrnl.c:3323
void ExDeletePagedLookasideList(PPAGED_LOOKASIDE_LIST lookaside)
Definition: ntoskrnl.c:2190
NTSTATUS MmProtectMdlSystemAddress(PMDL MemoryDescriptorList, ULONG NewProtect)
Definition: ntoskrnl.c:3151
void MmLockPagableSectionByHandle(PVOID ImageSectionHandle)
Definition: ntoskrnl.c:2686
PEPROCESS IoGetRequestorProcess(IRP *irp)
Definition: ntoskrnl.c:4032
PVOID IoAllocateErrorLogEntry(PVOID IoObject, UCHAR EntrySize)
Definition: ntoskrnl.c:1078
NTSTATUS PsReferenceProcessFilePointer(PEPROCESS process, FILE_OBJECT **file)
Definition: ntoskrnl.c:3067
static void set_service_status(SERVICE_STATUS_HANDLE handle, DWORD state, DWORD accepted)
Definition: ntoskrnl.c:799
static NTSTATUS dispatch_free(struct dispatch_context *context)
Definition: ntoskrnl.c:763
NTSTATUS PsLookupProcessByProcessId(HANDLE processid, PEPROCESS *process)
Definition: ntoskrnl.c:2264
NTSTATUS(* dispatch_func)(struct dispatch_context *context)
Definition: ntoskrnl.c:783
static void build_driver_keypath(const WCHAR *name, UNICODE_STRING *keypath)
Definition: ntoskrnl.c:1359
void IoDeleteDevice(DEVICE_OBJECT *device)
Definition: ntoskrnl.c:1561
void KeRevertToUserAffinityThreadEx(KAFFINITY affinity)
Definition: ntoskrnl.c:2530
NTSTATUS ObRegisterCallbacks(POB_CALLBACK_REGISTRATION callback, void **handle)
Definition: ntoskrnl.c:2876
BOOL DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
Definition: ntoskrnl.c:4274
NTSTATUS IoReportResourceUsage(UNICODE_STRING *name, DRIVER_OBJECT *drv_obj, CM_RESOURCE_LIST *drv_list, ULONG drv_size, DRIVER_OBJECT *dev_obj, CM_RESOURCE_LIST *dev_list, ULONG dev_size, BOOLEAN overwrite, BOOLEAN *conflict)
Definition: ntoskrnl.c:1887
NTSTATUS IoRegisterShutdownNotification(PDEVICE_OBJECT obj)
Definition: ntoskrnl.c:1854
KAFFINITY KeQueryActiveProcessors(void)
Definition: ntoskrnl.c:2420
void KeGenericCallDpc(PKDEFERRED_ROUTINE routine, void *context)
Definition: ntoskrnl.c:4097
void IoReuseIrp(IRP *irp, NTSTATUS iostatus)
Definition: ntoskrnl.c:985
static void initialize_lookaside_list(GENERAL_LOOKASIDE *lookaside, PALLOCATE_FUNCTION allocate, PFREE_FUNCTION free, ULONG type, SIZE_T size, ULONG tag)
Definition: ntoskrnl.c:2118
NTSTATUS ExCreateCallback(PCALLBACK_OBJECT *obj, POBJECT_ATTRIBUTES attr, BOOLEAN create, BOOLEAN allow_multiple)
Definition: ntoskrnl.c:2078
void IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject)
Definition: ntoskrnl.c:2578
POBJECT_TYPE PsThreadType
Definition: ntoskrnl.c:2333
static void dispatch_irp(DEVICE_OBJECT *device, IRP *irp, struct dispatch_context *context)
Definition: ntoskrnl.c:492
NTSTATUS IoCallDriver(DEVICE_OBJECT *device, IRP *irp)
Definition: ntoskrnl.c:1692
PIO_WORKITEM IoAllocateWorkItem(PDEVICE_OBJECT device)
Definition: ntoskrnl.c:1142
void KeQuerySystemTime(LARGE_INTEGER *time)
Definition: ntoskrnl.c:2453
PCONFIGURATION_INFORMATION IoGetConfigurationInformation(void)
Definition: ntoskrnl.c:1739
static void free_driver_object(void *obj)
Definition: ntoskrnl.c:1392
HANDLE PsGetCurrentThreadId(void)
Definition: ntoskrnl.c:2941
static DWORD client_tid
Definition: ntoskrnl.c:84
POBJECT_TYPE IoFileObjectType
Definition: ntoskrnl.c:413
ULONG KeQueryActiveProcessorCountEx(USHORT group_number)
Definition: ntoskrnl.c:2428
void KeUnstackDetachProcess(KAPC_STATE *apc_state)
Definition: ntoskrnl.c:4254
void PsReleaseProcessExitSynchronization(PEPROCESS process)
Definition: ntoskrnl.c:3870
LONG NTOSKRNL_InterlockedExchangeAdd(LONG volatile *dest, LONG incr)
Definition: ntoskrnl.c:2020
PIRP IoAllocateIrp(CCHAR stack_size, BOOLEAN charge_quota)
Definition: ntoskrnl.c:1030
NTSTATUS IoGetDeviceInterfaces(const GUID *InterfaceClassGuid, PDEVICE_OBJECT PhysicalDeviceObject, ULONG Flags, PWSTR *SymbolicLinkList)
Definition: ntoskrnl.c:1660
NTSTATUS CmUnRegisterCallback(LARGE_INTEGER cookie)
Definition: ntoskrnl.c:3393
NTSTATUS ZwUnloadDriver(const UNICODE_STRING *service_name)
Definition: ntoskrnl.c:3789
void KeInitializeDpc(KDPC *dpc, PKDEFERRED_ROUTINE deferred_routine, void *deferred_context)
Definition: ntoskrnl.c:3169
ULONG ExSetTimerResolution(ULONG time, BOOLEAN set_resolution)
Definition: ntoskrnl.c:4023
POBJECT_TYPE ObGetObjectType(void *object)
Definition: ntoskrnl.c:253
NTSTATUS IoUnregisterPlugPlayNotification(PVOID notification)
Definition: ntoskrnl.c:3302
void IoInitializeIrp(IRP *irp, USHORT size, CCHAR stack_size)
Definition: ntoskrnl.c:970
BOOLEAN Ke386SetIoAccessMap(ULONG flag, PVOID buffer)
Definition: ntoskrnl.c:3256
NTSTATUS FsRtlRegisterUncProvider(PHANDLE MupHandle, PUNICODE_STRING RedirDevName, BOOLEAN MailslotsSupported)
Definition: ntoskrnl.c:2221
BOOLEAN FsRtlIsNameInExpression(PUNICODE_STRING expression, PUNICODE_STRING name, BOOLEAN ignore, PWCH upcase)
Definition: ntoskrnl.c:2211
HANDLE PsGetThreadId(PETHREAD thread)
Definition: ntoskrnl.c:2387
static void * ldr_notify_cookie
Definition: ntoskrnl.c:88
PRKTHREAD KeGetCurrentThread(void)
Definition: ntoskrnl.c:2339
static struct _OBJECT_TYPE file_type
Definition: ntoskrnl.c:408
NTSTATUS PsSetCreateProcessNotifyRoutine(PCREATE_PROCESS_NOTIFY_ROUTINE callback, BOOLEAN remove)
Definition: ntoskrnl.c:3006
BOOLEAN MmIsAddressValid(PVOID VirtualAddress)
Definition: ntoskrnl.c:2667
PVOID ExAllocatePool(POOL_TYPE type, SIZE_T size)
Definition: ntoskrnl.c:2039
static PLOAD_IMAGE_NOTIFY_ROUTINE load_image_notify_routines[8]
Definition: ntoskrnl.c:90
POBJECT_TYPE PsProcessType
Definition: ntoskrnl.c:2250
PVOID ExAllocatePoolWithQuota(POOL_TYPE type, SIZE_T size)
Definition: ntoskrnl.c:2048
void IoRegisterDriverReinitialization(PDRIVER_OBJECT obj, PDRIVER_REINITIALIZE reinit, PVOID context)
Definition: ntoskrnl.c:1838
NTSTATUS CmRegisterCallback(EX_CALLBACK_FUNCTION *function, void *context, LARGE_INTEGER *cookie)
Definition: ntoskrnl.c:3384
void ExfUnblockPushLock(EX_PUSH_LOCK *lock, PEX_PUSH_LOCK_WAIT_BLOCK block)
Definition: ntoskrnl.c:3880
NTSTATUS IoCreateDriver(UNICODE_STRING *name, PDRIVER_INITIALIZE init)
Definition: ntoskrnl.c:1415
NTSTATUS MmCreateSection(HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr, LARGE_INTEGER *size, ULONG protect, ULONG alloc_attr, HANDLE file, FILE_OBJECT *file_obj)
Definition: ntoskrnl.c:2636
static DWORD dpc_call_tls_index
Definition: ntoskrnl.c:77
PDEVICE_OBJECT IoGetRelatedDeviceObject(PFILE_OBJECT obj)
Definition: ntoskrnl.c:1728
NTSTATUS IoCreateFile(HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr, IO_STATUS_BLOCK *io, LARGE_INTEGER *alloc_size, ULONG attributes, ULONG sharing, ULONG disposition, ULONG create_options, void *ea_buffer, ULONG ea_length, CREATE_FILE_TYPE file_type, void *parameters, ULONG options)
Definition: ntoskrnl.c:3815
void ObReferenceObject(void *obj)
Definition: ntoskrnl.c:221
NTSTATUS IoCreateUnprotectedSymbolicLink(UNICODE_STRING *name, UNICODE_STRING *target)
Definition: ntoskrnl.c:1613
static const WCHAR thread_type_name[]
Definition: ntoskrnl.c:2325
void IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject)
Definition: ntoskrnl.c:2551
void IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: ntoskrnl.c:1021
PIRP IoBuildDeviceIoControlRequest(ULONG code, PDEVICE_OBJECT device, PVOID in_buff, ULONG in_len, PVOID out_buff, ULONG out_len, BOOLEAN internal, PKEVENT event, PIO_STATUS_BLOCK iosb)
Definition: ntoskrnl.c:1226
static void delete_lookaside_list(GENERAL_LOOKASIDE *lookaside)
Definition: ntoskrnl.c:2170
void IoDeleteDriver(DRIVER_OBJECT *driver_object)
Definition: ntoskrnl.c:1465
void ObfDereferenceObject(void *obj)
Definition: ntoskrnl.c:2868
PEPROCESS PsInitialSystemProcess
Definition: ntoskrnl.c:845
static void unload_driver(struct wine_rb_entry *entry, void *context)
Definition: ntoskrnl.c:812
static CRITICAL_SECTION obref_cs
Definition: ntoskrnl.c:180
void KeSetImportanceDpc(PRKDPC dpc, KDPC_IMPORTANCE importance)
Definition: ntoskrnl.c:3181
void KeSetSystemAffinityThread(KAFFINITY affinity)
Definition: ntoskrnl.c:2493
NTSTATUS PsResumeProcess(PEPROCESS process)
Definition: ntoskrnl.c:3097
void KeBugCheckEx(ULONG code, ULONG_PTR param1, ULONG_PTR param2, ULONG_PTR param3, ULONG_PTR param4)
Definition: ntoskrnl.c:3359
NTSTATUS kernel_object_from_handle(HANDLE handle, POBJECT_TYPE type, void **ret)
Definition: ntoskrnl.c:273
void ExUnregisterCallback(void *callback_registration)
Definition: ntoskrnl.c:2095
NTSTATUS KeExpandKernelStackAndCalloutEx(PEXPAND_STACK_CALLOUT callout, void *parameter, SIZE_T size, BOOLEAN wait, void *context)
Definition: ntoskrnl.c:2559
PIRP IoBuildSynchronousFsdRequest(ULONG majorfunc, PDEVICE_OBJECT device, PVOID buffer, ULONG length, PLARGE_INTEGER startoffset, PKEVENT event, PIO_STATUS_BLOCK iosb)
Definition: ntoskrnl.c:1344
HANDLE PsGetProcessId(PEPROCESS process)
Definition: ntoskrnl.c:2283
NTSTATUS IoWMIRegistrationControl(PDEVICE_OBJECT DeviceObject, ULONG Action)
Definition: ntoskrnl.c:3205
static NTSTATUS unhandled_irp(DEVICE_OBJECT *device, IRP *irp)
Definition: ntoskrnl.c:1383
NTSTATUS FsRtlRegisterFileSystemFilterCallbacks(DRIVER_OBJECT *object, PFS_FILTER_CALLBACKS callbacks)
Definition: ntoskrnl.c:3888
static NTSTATUS dispatch_flush(struct dispatch_context *context)
Definition: ntoskrnl.c:671
NTSTATUS wine_ntoskrnl_main_loop(HANDLE stop_event)
Definition: ntoskrnl.c:850
NTSTATUS IoRegisterPlugPlayNotification(IO_NOTIFICATION_EVENT_CATEGORY category, ULONG flags, PVOID data, PDRIVER_OBJECT driver, PDRIVER_NOTIFICATION_CALLBACK_ROUTINE callback, PVOID context, PVOID *notification)
Definition: ntoskrnl.c:3291
static const WCHAR device_type_name[]
Definition: ntoskrnl.c:1477
void ExInitializePagedLookasideList(PPAGED_LOOKASIDE_LIST lookaside, PALLOCATE_FUNCTION allocate, PFREE_FUNCTION free, ULONG flags, SIZE_T size, ULONG tag, USHORT depth)
Definition: ntoskrnl.c:2158
void READ_REGISTER_BUFFER_UCHAR(PUCHAR Register, PUCHAR Buffer, ULONG Count)
Definition: ntoskrnl.c:3197
void MmResetDriverPaging(PVOID AddrInSection)
Definition: ntoskrnl.c:2740
NTSTATUS ExUuidCreate(UUID *uuid)
Definition: ntoskrnl.c:4003
static void * get_rva(HMODULE module, DWORD va)
Definition: ntoskrnl.c:3498
void ProbeForWrite(void *address, SIZE_T length, ULONG alignment)
Definition: ntoskrnl.c:3376
static HANDLE get_device_manager(void)
Definition: ntoskrnl.c:113
static NTSTATUS init_driver(DRIVER_OBJECT *driver_object, UNICODE_STRING *keyname)
Definition: ntoskrnl.c:3673
NTSTATUS IoReportResourceForDetection(DRIVER_OBJECT *drv_obj, CM_RESOURCE_LIST *drv_list, ULONG drv_size, DEVICE_OBJECT *dev_obj, CM_RESOURCE_LIST *dev_list, ULONG dev_size, BOOLEAN *conflict)
Definition: ntoskrnl.c:1873
void MmUnlockPages(PMDLX MemoryDescriptorList)
Definition: ntoskrnl.c:2749
static void free_kernel_object(void *obj)
Definition: ntoskrnl.c:148
LONG NTOSKRNL_InterlockedExchange(LONG volatile *dest, LONG val)
Definition: ntoskrnl.c:2010
void MmUnlockPagableImageSection(PVOID ImageSectionHandle)
Definition: ntoskrnl.c:2713
void IoStartNextPacket(PDEVICE_OBJECT deviceobject, BOOLEAN cancelable)
Definition: ntoskrnl.c:3265
static int wine_drivers_rb_compare(const void *key, const struct wine_rb_entry *entry)
Definition: ntoskrnl.c:101
NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES attr, POBJECT_TYPE type, KPROCESSOR_MODE mode, ACCESS_STATE *access_state, ACCESS_MASK access, PVOID ctx, HANDLE *handle)
Definition: ntoskrnl.c:2812
static const WCHAR driver_type_name[]
Definition: ntoskrnl.c:1400
void ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST lookaside)
Definition: ntoskrnl.c:2180
void ProbeForRead(void *address, SIZE_T length, ULONG alignment)
Definition: ntoskrnl.c:3368
NTSTATUS IoInitializeTimer(PDEVICE_OBJECT DeviceObject, PIO_TIMER_ROUTINE TimerRoutine, PVOID Context)
Definition: ntoskrnl.c:1000
void MmUnmapIoSpace(PVOID BaseAddress, SIZE_T NumberOfBytes)
Definition: ntoskrnl.c:2758
NTSTATUS IoCsqInitialize(PIO_CSQ csq, PIO_CSQ_INSERT_IRP insert_irp, PIO_CSQ_REMOVE_IRP remove_irp, PIO_CSQ_PEEK_NEXT_IRP peek_irp, PIO_CSQ_ACQUIRE_LOCK acquire_lock, PIO_CSQ_RELEASE_LOCK release_lock, PIO_CSQ_COMPLETE_CANCELED_IRP complete_irp)
Definition: ntoskrnl.c:3311
static CRITICAL_SECTION irp_completion_cs
Definition: ntoskrnl.c:424
HANDLE PsGetProcessInheritedFromUniqueProcessId(PEPROCESS process)
Definition: ntoskrnl.c:2292
static HMODULE load_driver(const WCHAR *driver_name, const UNICODE_STRING *keyname)
Definition: ntoskrnl.c:3571
NTSTATUS IofCallDriver(DEVICE_OBJECT *device, IRP *irp)
Definition: ntoskrnl.c:1718
PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE type, SIZE_T size, ULONG tag)
Definition: ntoskrnl.c:2069
void IoFreeMdl(PMDL mdl)
Definition: ntoskrnl.c:1125
static NTSTATUS dispatch_read(struct dispatch_context *context)
Definition: ntoskrnl.c:593
NTSTATUS ObReferenceObjectByPointer(void *obj, ACCESS_MASK access, POBJECT_TYPE type, KPROCESSOR_MODE mode)
Definition: ntoskrnl.c:2844
void IoFreeIrp(IRP *irp)
Definition: ntoskrnl.c:1057
static NTSTATUS dispatch_close(struct dispatch_context *context)
Definition: ntoskrnl.c:555
BOOLEAN IoCancelIrp(IRP *irp)
Definition: ntoskrnl.c:1964
void MmFreeNonCachedMemory(void *addr, SIZE_T size)
Definition: ntoskrnl.c:2648
HANDLE PsGetThreadProcessId(PETHREAD thread)
Definition: ntoskrnl.c:2396
BOOLEAN SeSinglePrivilegeCheck(LUID privilege, KPROCESSOR_MODE mode)
Definition: ntoskrnl.c:3897
BOOLEAN SePrivilegeCheck(PRIVILEGE_SET *privileges, SECURITY_SUBJECT_CONTEXT *context, KPROCESSOR_MODE mode)
Definition: ntoskrnl.c:3907
BOOLEAN KeSignalCallDpcSynchronize(void *barrier)
Definition: ntoskrnl.c:4178
void KeRevertToUserAffinityThread(void)
Definition: ntoskrnl.c:2525
void IoDetachDevice(DEVICE_OBJECT *device)
Definition: ntoskrnl.c:1205
HANDLE PsGetCurrentProcessId(void)
Definition: ntoskrnl.c:2932
void KeLeaveCriticalRegion(void)
Definition: ntoskrnl.c:3332
void IoRegisterBootDriverReinitialization(DRIVER_OBJECT *driver, PDRIVER_REINITIALIZE proc, void *ctx)
Definition: ntoskrnl.c:1846
KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority)
Definition: ntoskrnl.c:2484
BOOLEAN KdRefreshDebuggerNotPresent(void)
Definition: ntoskrnl.c:4058
PVOID MmAllocateNonCachedMemory(SIZE_T size)
Definition: ntoskrnl.c:2586
NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle, ULONG DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ProcessHandle, PCLIENT_ID ClientId, PKSTART_ROUTINE StartRoutine, PVOID StartContext)
Definition: ntoskrnl.c:2918
static HANDLE ntoskrnl_heap
Definition: ntoskrnl.c:86
NTSTATUS PsImpersonateClient(PETHREAD Thread, PACCESS_TOKEN Token, BOOLEAN CopyOnOpen, BOOLEAN EffectiveOnly, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: ntoskrnl.c:2985
static CRITICAL_SECTION drivers_cs
Definition: ntoskrnl.c:111
BOOLEAN RtlIsNtDdiVersionAvailable(ULONG version)
Definition: ntoskrnl.c:4052
void IoUnregisterShutdownNotification(PDEVICE_OBJECT obj)
Definition: ntoskrnl.c:1864
void MmProbeAndLockPages(PMDLX MemoryDescriptorList, KPROCESSOR_MODE AccessMode, LOCK_OPERATION Operation)
Definition: ntoskrnl.c:2731
DEVICE_OBJECT * IoGetAttachedDeviceReference(DEVICE_OBJECT *device)
Definition: ntoskrnl.c:2907
void ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST lookaside, PALLOCATE_FUNCTION allocate, PFREE_FUNCTION free, ULONG flags, SIZE_T size, ULONG tag, USHORT depth)
Definition: ntoskrnl.c:2143
PIRP IoBuildAsynchronousFsdRequest(ULONG majorfunc, DEVICE_OBJECT *device, void *buffer, ULONG length, LARGE_INTEGER *startoffset, IO_STATUS_BLOCK *iosb)
Definition: ntoskrnl.c:1289
PKEVENT IoCreateNotificationEvent(UNICODE_STRING *name, HANDLE *handle)
Definition: ntoskrnl.c:3827
KSYSTEM_TIME KeTickCount
Definition: ntoskrnl.c:61
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4]
Definition: ntoskrnl.c:71
static const WCHAR token_type_name[]
Definition: ntoskrnl.c:3979
NTSTATUS PsSetCreateThreadNotifyRoutine(PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
Definition: ntoskrnl.c:3026
NTSTATUS PsAcquireProcessExitSynchronization(PEPROCESS process)
Definition: ntoskrnl.c:3860
BOOLEAN MmIsThisAnNtAsSystem(void)
Definition: ntoskrnl.c:3142