/* * ntoskrnl.exe implementation * * Copyright (C) 2007 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" #include "wine/port.h" #include #define NONAMELESSUNION #define NONAMELESSSTRUCT #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" #include "winternl.h" #include "ddk/wdm.h" #include "wine/unicode.h" #include "wine/server.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); static inline LPCSTR debugstr_us( const UNICODE_STRING *us ) { if (!us) return ""; return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) ); } static HANDLE get_device_manager(void) { static HANDLE device_manager; HANDLE handle = 0, ret = device_manager; if (!ret) { SERVER_START_REQ( create_device_manager ) { req->access = SYNCHRONIZE; req->attributes = 0; if (!wine_server_call( req )) handle = reply->handle; } SERVER_END_REQ; if (!handle) { ERR( "failed to create the device manager\n" ); return 0; } if (!(ret = InterlockedCompareExchangePointer( &device_manager, handle, 0 ))) ret = handle; else NtClose( handle ); /* somebody beat us to it */ } return ret; } /*********************************************************************** * IoCreateDevice (NTOSKRNL.EXE.@) */ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size, UNICODE_STRING *name, DEVICE_TYPE type, ULONG characteristics, BOOLEAN exclusive, DEVICE_OBJECT **ret_device ) { NTSTATUS status; DEVICE_OBJECT *device; HANDLE handle = 0; HANDLE manager = get_device_manager(); TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n", driver, ext_size, debugstr_us(name), type, characteristics, exclusive, ret_device ); if (!(device = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*device) + ext_size ))) return STATUS_NO_MEMORY; SERVER_START_REQ( create_device ) { req->access = 0; req->attributes = 0; req->rootdir = 0; req->manager = manager; req->user_ptr = device; if (name) wine_server_add_data( req, name->Buffer, name->Length ); if (!(status = wine_server_call( req ))) handle = reply->handle; } SERVER_END_REQ; if (status == STATUS_SUCCESS) { device->DriverObject = driver; device->DeviceExtension = device + 1; device->DeviceType = type; device->Reserved = handle; device->NextDevice = driver->DeviceObject; driver->DeviceObject = device; *ret_device = device; } else HeapFree( GetProcessHeap(), 0, device ); return status; } /*********************************************************************** * IoDeleteDevice (NTOSKRNL.EXE.@) */ void WINAPI IoDeleteDevice( DEVICE_OBJECT *device ) { NTSTATUS status; TRACE( "%p\n", device ); SERVER_START_REQ( delete_device ) { req->handle = device->Reserved; status = wine_server_call( req ); } SERVER_END_REQ; if (status == STATUS_SUCCESS) { DEVICE_OBJECT **prev = &device->DriverObject->DeviceObject; while (*prev && *prev != device) prev = &(*prev)->NextDevice; if (*prev) *prev = (*prev)->NextDevice; NtClose( device->Reserved ); HeapFree( GetProcessHeap(), 0, device ); } } /*********************************************************************** * IoCreateSymbolicLink (NTOSKRNL.EXE.@) */ NTSTATUS WINAPI IoCreateSymbolicLink( UNICODE_STRING *name, UNICODE_STRING *target ) { HANDLE handle; OBJECT_ATTRIBUTES attr; attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.ObjectName = name; attr.Attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; TRACE( "%s -> %s\n", debugstr_us(name), debugstr_us(target) ); /* FIXME: store handle somewhere */ return NtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, target ); } /***************************************************** * DllMain */ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { switch(reason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( inst ); break; } return TRUE; }