/*
* 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 <stdarg.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
#include "excpt.h"
#include "ddk/wdm.h"
#include "wine/unicode.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
WINE_DECLARE_DEBUG_CHANNEL(relay);
KSYSTEM_TIME KeTickCount;
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
PULONG_PTR Base;
PULONG Count;
ULONG Limit;
PUCHAR Number;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4];
typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
#ifdef __i386__
#define DEFINE_FASTCALL1_ENTRYPOINT( name ) /
__ASM_GLOBAL_FUNC( name, /
"popl %eax/n/t" /
"pushl %ecx/n/t" /
"pushl %eax/n/t" /
"jmp " __ASM_NAME("__regs_") #name )
#define DEFINE_FASTCALL2_ENTRYPOINT( name ) /
__ASM_GLOBAL_FUNC( name, /
"popl %eax/n/t" /
"pushl %edx/n/t" /
"pushl %ecx/n/t" /
"pushl %eax/n/t" /
"jmp " __ASM_NAME("__regs_") #name )
#endif
static inline LPCSTR debugstr_us( const UNICODE_STRING *us )
{
if (!us) return "<null>";
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;
}
/* exception handler for emulation of privileged instructions */
static LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs )
{
extern DWORD __wine_emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT86 *context );
EXCEPTION_RECORD *record = ptrs->ExceptionRecord;
CONTEXT86 *context = ptrs->ContextRecord;
if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)
{
if (__wine_emulate_instruction( record, context ) == ExceptionContinueExecution)
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
/* process an ioctl request for a given device */
static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
void *out_buff, ULONG *out_size )
{
IRP irp;
MDL mdl;
IO_STACK_LOCATION irpsp;
PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
NTSTATUS status;
LARGE_INTEGER count;
TRACE( "ioctl %x device %p in_size %u out_size %u/n", code, device, in_size, *out_size );
/* so we can spot things that we should initialize */
memset( &irp, 0x55, sizeof(irp) );
memset( &irpsp, 0x66, sizeof(irpsp) );
memset( &mdl, 0x77, sizeof(mdl) );
irp.RequestorMode = UserMode;
irp.AssociatedIrp.SystemBuffer = in_buff;
irp.UserBuffer = out_buff;
irp.MdlAddress = &mdl;
irp.Tail.Overlay.s.u.CurrentStackLocation = &irpsp;
irpsp.MajorFunction = IRP_MJ_DEVICE_CONTROL;
irpsp.Parameters.DeviceIoControl.OutputBufferLength = *out_size;
irpsp.Parameters.DeviceIoControl.InputBufferLength = in_size;
irpsp.Parameters.DeviceIoControl.IoControlCode = code;
irpsp.Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
irpsp.DeviceObject = device;
mdl.Next = NULL;
mdl.Size = 0;
mdl.StartVa = out_buff;
mdl.ByteCount = *out_size;
mdl.ByteOffset = 0;
device->CurrentIrp = &irp;
KeQueryTickCount( &count ); /* update the global KeTickCount */
if (TRACE_ON(relay))
DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)/n",
GetCurrentThreadId(), dispatch, device, &irp );
status = dispatch( device, &irp );
if (TRACE_ON(relay))
DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x/n",
GetCurrentThreadId(), dispatch, device, &irp, status );
*out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
return irp.IoStatus.u.Status;
}
/***********************************************************************
* wine_ntoskrnl_main_loop (Not a Windows API)
*/
NTSTATUS wine_ntoskrnl_main_loop( HANDLE stop_event )
{
HANDLE manager = get_device_manager();
HANDLE ioctl = 0;
NTSTATUS status = STATUS_SUCCESS;
ULONG code = 0;
void *in_buff, *out_buff = NULL;
DEVICE_OBJECT *device = NULL;
ULONG in_size = 4096, out_size = 0;
HANDLE handles[2];
if (!(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size )))
{
ERR( "failed to allocate buffer/n" );
return STATUS_NO_MEMORY;
}
handles[0] = stop_event;
handles[1] = manager;
for (;;)
{
SERVER_START_REQ( get_next_device_request )
{
req->manager = manager;
req->prev = ioctl;
req->status = status;
wine_server_add_data( req, out_buff, out_size );
wine_server_set_reply( req, in_buff, in_size );
if (!(status = wine_server_call( req )))
{
code = reply->code;
ioctl = reply->next;
device = reply->user_ptr;
in_size = reply->in_size;
out_size = reply->out_size;
}
else
{
ioctl = 0; /* no previous ioctl */
out_size = 0;
in_size = reply->in_size;
}
}
SERVER_END_REQ;
switch(status)
{
case STATUS_SUCCESS:
HeapFree( GetProcessHeap(), 0, out_buff );
if (out_size) out_buff = HeapAlloc( GetProcessHeap(), 0, out_size );
else out_buff = NULL;
status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
break;
case STATUS_BUFFER_OVERFLOW:
HeapFree( GetProcessHeap(), 0, in_buff );
in_buff = HeapAlloc( GetProcessHeap(), 0, in_size );
/* restart with larger buffer */
break;
case STATUS_PENDING:
if (WaitForMultipleObjects( 2, handles, FALSE, INFINITE ) == WAIT_OBJECT_0)
return STATUS_SUCCESS;
break;
}
}
}
/***********************************************************************
* IoAllocateMdl (NTOSKRNL.EXE.@)
*/
PMDL WINAPI IoAllocateMdl( PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN ChargeQuota, PIRP Irp )
{
FIXME( "stub: %p, %u, %i, %i, %p/n", VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp );
return NULL;
}
/***********************************************************************
* IoAllocateWorkItem (NTOSKRNL.EXE.@)
*/
PIO_WORKITEM WINAPI IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject )
{
FIXME( "stub: %p/n", DeviceObject );
return NULL;
}
/***********************************************************************
* IoCreateDriver (NTOSKRNL.EXE.@)
*/
NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
{
DRIVER_OBJECT *driver;
DRIVER_EXTENSION *extension;
NTSTATUS status;
if (!(driver = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(*driver) + sizeof(*extension) )))
return STATUS_NO_MEMORY;
if ((status = RtlDuplicateUnicodeString( 1, name, &driver->DriverName )))
{
RtlFreeHeap( GetProcessHeap(), 0, driver );
return status;
}
extension = (DRIVER_EXTENSION *)(driver + 1);
driver->Size = sizeof(*driver);
driver->DriverInit = init;
driver->DriverExtension = extension;
extension->DriverObject = driver;
extension->ServiceKeyName = driver->DriverName;
status = driver->DriverInit( driver, name );
if (status)
{
RtlFreeUnicodeString( &driver->DriverName );
RtlFreeHeap( GetProcessHeap(), 0, driver );
}
return status;
}
/***********************************************************************
* IoDeleteDriver (NTOSKRNL.EXE.@)
*/
void WINAPI IoDeleteDriver( DRIVER_OBJECT *driver )
{
RtlFreeUnicodeString( &driver->DriverName );
RtlFreeHeap( GetProcessHeap(), 0, driver );
}
/***********************************************************************
* 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 );
}
/***********************************************************************
* IofCompleteRequest (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL2_ENTRYPOINT
DEFINE_FASTCALL2_ENTRYPOINT( IofCompleteRequest )
void WINAPI __regs_IofCompleteRequest( IRP *irp, UCHAR priority_boost )
#else
void WINAPI IofCompleteRequest( IRP *irp, UCHAR priority_boost )
#endif
{
TRACE( "%p %u/n", irp, priority_boost );
/* nothing to do for now */
}
/***********************************************************************
* InterlockedCompareExchange (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL2_ENTRYPOINT
DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedCompareExchange )
LONG WINAPI __regs_NTOSKRNL_InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
#else
LONG WINAPI NTOSKRNL_InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
#endif
{
return InterlockedCompareExchange( dest, xchg, compare );
}
/***********************************************************************
* InterlockedDecrement (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL1_ENTRYPOINT
DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedDecrement )
LONG WINAPI __regs_NTOSKRNL_InterlockedDecrement( LONG volatile *dest )
#else
LONG WINAPI NTOSKRNL_InterlockedDecrement( LONG volatile *dest )
#endif
{
return InterlockedDecrement( dest );
}
/***********************************************************************
* InterlockedExchange (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL2_ENTRYPOINT
DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchange )
LONG WINAPI __regs_NTOSKRNL_InterlockedExchange( LONG volatile *dest, LONG val )
#else
LONG WINAPI NTOSKRNL_InterlockedExchange( LONG volatile *dest, LONG val )
#endif
{
return InterlockedExchange( dest, val );
}
/***********************************************************************
* InterlockedExchangeAdd (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL2_ENTRYPOINT
DEFINE_FASTCALL2_ENTRYPOINT( NTOSKRNL_InterlockedExchangeAdd )
LONG WINAPI __regs_NTOSKRNL_InterlockedExchangeAdd( LONG volatile *dest, LONG incr )
#else
LONG WINAPI NTOSKRNL_InterlockedExchangeAdd( LONG volatile *dest, LONG incr )
#endif
{
return InterlockedExchangeAdd( dest, incr );
}
/***********************************************************************
* InterlockedIncrement (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL1_ENTRYPOINT
DEFINE_FASTCALL1_ENTRYPOINT( NTOSKRNL_InterlockedIncrement )
LONG WINAPI __regs_NTOSKRNL_InterlockedIncrement( LONG volatile *dest )
#else
LONG WINAPI NTOSKRNL_InterlockedIncrement( LONG volatile *dest )
#endif
{
return InterlockedIncrement( dest );
}
/***********************************************************************
* ExAllocatePool (NTOSKRNL.EXE.@)
*/
PVOID WINAPI ExAllocatePool( POOL_TYPE type, SIZE_T size )
{
return ExAllocatePoolWithTag( type, size, 0 );
}
/***********************************************************************
* ExAllocatePoolWithQuota (NTOSKRNL.EXE.@)
*/
PVOID WINAPI ExAllocatePoolWithQuota( POOL_TYPE type, SIZE_T size )
{
return ExAllocatePoolWithTag( type, size, 0 );
}
/***********************************************************************
* ExAllocatePoolWithTag (NTOSKRNL.EXE.@)
*/
PVOID WINAPI ExAllocatePoolWithTag( POOL_TYPE type, SIZE_T size, ULONG tag )
{
/* FIXME: handle page alignment constraints */
void *ret = HeapAlloc( GetProcessHeap(), 0, size );
TRACE( "%lu pool %u -> %p/n", size, type, ret );
return ret;
}
/***********************************************************************
* ExAllocatePoolWithQuotaTag (NTOSKRNL.EXE.@)
*/
PVOID WINAPI ExAllocatePoolWithQuotaTag( POOL_TYPE type, SIZE_T size, ULONG tag )
{
return ExAllocatePoolWithTag( type, size, tag );
}
/***********************************************************************
* ExFreePool (NTOSKRNL.EXE.@)
*/
void WINAPI ExFreePool( void *ptr )
{
ExFreePoolWithTag( ptr, 0 );
}
/***********************************************************************
* ExFreePoolWithTag (NTOSKRNL.EXE.@)
*/
void WINAPI ExFreePoolWithTag( void *ptr, ULONG tag )
{
TRACE( "%p/n", ptr );
HeapFree( GetProcessHeap(), 0, ptr );
}
/***********************************************************************
* KeInitializeSpinLock (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeSpinLock( PKSPIN_LOCK SpinLock )
{
FIXME("%p/n", SpinLock);
}
/***********************************************************************
* KeInitializeTimerEx (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeTimerEx( PKTIMER Timer, TIMER_TYPE Type )
{
FIXME("%p %d/n", Timer, Type);
}
/***********************************************************************
* KeInitializeTimer (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeTimer( PKTIMER Timer )
{
KeInitializeTimerEx(Timer, NotificationTimer);
}
/**********************************************************************
* KeQueryActiveProcessors (NTOSKRNL.EXE.@)
*
* Return the active Processors as bitmask
*
* RETURNS
* active Processors as bitmask
*
*/
KAFFINITY WINAPI KeQueryActiveProcessors( void )
{
DWORD_PTR AffinityMask;
GetProcessAffinityMask( GetCurrentProcess(), &AffinityMask, NULL);
return AffinityMask;
}
/**********************************************************************
* KeQueryInterruptTime (NTOSKRNL.EXE.@)
*
* Return the interrupt time count
*
*/
ULONGLONG WINAPI KeQueryInterruptTime( void )
{
LARGE_INTEGER totaltime;
KeQueryTickCount(&totaltime);
return totaltime.QuadPart;
}
/***********************************************************************
* KeQuerySystemTime (NTOSKRNL.EXE.@)
*/
void WINAPI KeQuerySystemTime( LARGE_INTEGER *time )
{
NtQuerySystemTime( time );
}
/***********************************************************************
* KeQueryTickCount (NTOSKRNL.EXE.@)
*/
void WINAPI KeQueryTickCount( LARGE_INTEGER *count )
{
count->QuadPart = NtGetTickCount();
/* update the global variable too */
KeTickCount.LowPart = count->u.LowPart;
KeTickCount.High1Time = count->u.HighPart;
KeTickCount.High2Time = count->u.HighPart;
}
/***********************************************************************
* KeQueryTimeIncrement (NTOSKRNL.EXE.@)
*/
ULONG WINAPI KeQueryTimeIncrement(void)
{
return 10000;
}
/***********************************************************************
* MmAllocateNonCachedMemory (NTOSKRNL.EXE.@)
*/
PVOID WINAPI MmAllocateNonCachedMemory( SIZE_T size )
{
TRACE( "%lu/n", size );
return VirtualAlloc( NULL, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE|PAGE_NOCACHE );
}
/***********************************************************************
* MmFreeNonCachedMemory (NTOSKRNL.EXE.@)
*/
void WINAPI MmFreeNonCachedMemory( void *addr, SIZE_T size )
{
TRACE( "%p %lu/n", addr, size );
VirtualFree( addr, 0, MEM_RELEASE );
}
/***********************************************************************
* MmIsAddressValid (NTOSKRNL.EXE.@)
*
* Check if the process can access the virtual address without a pagefault
*
* PARAMS
* VirtualAddress [I] Address to check
*
* RETURNS
* Failure: FALSE
* Success: TRUE (Accessing the Address works without a Pagefault)
*
*/
BOOLEAN WINAPI MmIsAddressValid(PVOID VirtualAddress)
{
TRACE("(%p)/n", VirtualAddress);
return !IsBadWritePtr(VirtualAddress, 1);
}
/***********************************************************************
* MmPageEntireDriver (NTOSKRNL.EXE.@)
*/
PVOID WINAPI MmPageEntireDriver(PVOID AddrInSection)
{
TRACE("%p/n", AddrInSection);
return AddrInSection;
}
/***********************************************************************
* MmResetDriverPaging (NTOSKRNL.EXE.@)
*/
void WINAPI MmResetDriverPaging(PVOID AddrInSection)
{
TRACE("%p/n", AddrInSection);
}
/***********************************************************************
* PsCreateSystemThread (NTOSKRNL.EXE.@)
*/
NTSTATUS WINAPI PsCreateSystemThread(PHANDLE ThreadHandle, ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle, PCLIENT_ID ClientId,
PKSTART_ROUTINE StartRoutine, PVOID StartContext)
{
if (!ProcessHandle) ProcessHandle = GetCurrentProcess();
return RtlCreateUserThread(ProcessHandle, 0, FALSE, 0, 0,
0, StartRoutine, StartContext,
ThreadHandle, ClientId);
}
/***********************************************************************
* PsGetCurrentProcessId (NTOSKRNL.EXE.@)
*/
HANDLE WINAPI PsGetCurrentProcessId(void)
{
return (HANDLE)GetCurrentProcessId(); /* FIXME: not quite right... */
}
/***********************************************************************
* PsGetCurrentThreadId (NTOSKRNL.EXE.@)
*/
HANDLE WINAPI PsGetCurrentThreadId(void)
{
return (HANDLE)GetCurrentThreadId(); /* FIXME: not quite right... */
}
/***********************************************************************
* PsGetVersion (NTOSKRNL.EXE.@)
*/
BOOLEAN WINAPI PsGetVersion(ULONG *major, ULONG *minor, ULONG *build, UNICODE_STRING *version )
{
RTL_OSVERSIONINFOEXW info;
RtlGetVersion( &info );
if (major) *major = info.dwMajorVersion;
if (minor) *minor = info.dwMinorVersion;
if (build) *build = info.dwBuildNumber;
if (version)
{
#if 0 /* FIXME: GameGuard passes an uninitialized pointer in version->Buffer */
size_t len = min( strlenW(info.szCSDVersion)*sizeof(WCHAR), version->MaximumLength );
memcpy( version->Buffer, info.szCSDVersion, len );
if (len < version->MaximumLength) version->Buffer[len / sizeof(WCHAR)] = 0;
version->Length = len;
#endif
}
return TRUE;
}
/***********************************************************************
* PsSetCreateProcessNotifyRoutine (NTOSKRNL.EXE.@)
*/
NTSTATUS WINAPI PsSetCreateProcessNotifyRoutine( PCREATE_PROCESS_NOTIFY_ROUTINE callback, BOOLEAN remove )
{
FIXME( "stub: %p %d/n", callback, remove );
return STATUS_SUCCESS;
}
/*****************************************************
* DllMain
*/
BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
{
LARGE_INTEGER count;
switch(reason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls( inst );
RtlAddVectoredExceptionHandler( TRUE, vectored_handler );
KeQueryTickCount( &count ); /* initialize the global KeTickCount */
break;
}
return TRUE;
}
相关推荐
机械臂开发必备:KDL库正逆解与动力学实战指南
在机器人算法领域,运动学与动力学计算是机械臂控制、仿真与轨迹规划的核心基础。正运动学描述关节空间到笛卡尔空间的映射,逆运动学则需要求解复杂的非线性方程,工程实现时常面临数值稳定性与调试效率的挑战。KDL(Kinematics and Dynamics Library)作为ROS生态中广泛使用的开源库,提供了统一的模型描述与高效求解器,将正逆解、雅可比矩阵及动力学参数计算封装为简洁接口,大幅降低开发门槛。无论是机械臂的笛卡尔空间轨迹跟踪,还是基于动力学模型的前馈控制,KDL都展现出强大的工程价值。本文从运动学
漫谈Wine之一: WINE的系统结构
我们所要开发的Linux兼容内核主要的一个源泉就是Wine。另一方面,我们之所以要开发兼容内核的的重要原因之一,就是因为Wine不能很好地解决在Linux内核上运行Windows应用的问题。为此,我们应该对Wine进行比较深入的研究,取得对Wine的深入理解,特别是要搞清两个问题:1)Wine是什么样的?2)为什么Wine是那样的?如此才能明白我们为什么要开发兼容内核,以及我们将怎样来开发兼容内核
比较器和运算放大器-2
今天继续了解输入阻抗问题,观察下图:首先考虑在我们没有接运放时,A点输出电压为6V,当接入如图所示的阻抗时电压还是6V吗?共模电阻和红框内对地电阻并联,阻值变小,相当于5k,通过计算可以求得A点电压变为4V,这样A的值发生了改变,试想一下这样的信号接入到运放的两端是不是相当于比较的两端信号发生了改变,那结果一定会发生偏离。信号源一般内阻是不确定的,一般也不是很小,如果不想改变输入阻抗,那唯一的办法就是改变运放的内阻了,比如内阻改为100K,1M等,越大越好,是不是A点电压就会无限接近6V。
wine对iocp的模拟
status = NtCreateIoCompletion( &ret, IO_COMPLETION_ALL_ACCESS, NULL, dwNumberOfConcurrentThreads ); 按照在windows下对完成端口的使用,要使用完成端口首先要调用CreateIoCompletionPort来创建一个完成端口。 创建的调用类似于 第二个参数NULL。CreateIoCompl
SAP ABAP实战:用GN_DELIVERY_CREATE批量创建内部交货单的完整代码与避坑指南
本文详细介绍了在SAP ABAP开发中使用GN_DELIVERY_CREATE函数批量创建内部交货单的完整实现方案。通过数据结构设计、多源数据整合、批量处理逻辑和错误处理机制等核心环节的深入解析,帮助开发者高效完成物流单据自动化处理,特别针对VL31N/VL32N等常见场景提供避坑指南。
VTK API 详解(134):vtkOBJWriter - 写入 OBJ 模型
是 VTK 中用于将数据写入 Wavefront OBJ 文件格式的类。OBJ 格式是广泛支持的 3D 网格模型格式,支持顶点、面和基本几何信息的保存,便于模型在多种三维软件间交换。
undocumented function--还原的IoCreateDriver()
通过WinDbg得到的反汇编代码来重写的IoCreateDriver(),完成之后对它的大概流程有了基本的了解。这个函数的目的是 依据提供的两个参数,一个是名称,一个是驱动初始化例程,来创建一个轻量级的驱动程序—功能不完善;初始化例程是完成相关任务。写完之后感觉有什么不对,有些地方将函数往字符串的地址拷,有的地方调用字符串。有的地方没看明白,仅供参考:(。NTSTATTUS IoCreateDriv
ARM Linux工控板+C# .NET Core:倍福ADS协议轻量化工业控制(附跨平台部署代码)
某自动化设备厂的倍福PLC控制系统曾依赖传统x86工控机:单台设备需配备1台Intel i5工控机(成本约8000元),功耗30W+,且Windows系统稳定性受工业环境干扰(如电磁辐射导致蓝屏)。更棘手的是,设备需部署在产线边缘(空间狭小),x86工控机的体积(4U机架)和散热需求(风扇噪音)难以适配;而多设备部署时,高硬件成本和高功耗导致年运维成本超20万元。
64位环境下已签名驱动中实现加载未签名驱动
在64位环境下已签名驱动中实现加载未签名驱动,例如要加载路径为C:\test.sys的未签名驱动程序,步骤如下: (1)将C:\test.sys按照内存对齐方式拷贝到内存中。 (2)对test内存映像进行重定位。 (3)修复test内存映像的导入表。 (4)获取test内存映像中入口点DrverEntry地址,之后调用IoCreateDriver创建驱动。(IoCreateDrive...
YOLOv11架构革新:华为VanillaNet与BiFPN深度融合的突破性改进实战指南
购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!
睿抗机器人魔力元宝在完成任务过程中如何使机械臂先到达白色盒子上方而不是先到达工作台?
🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up! 备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。
Windows内核原理与实现之驱动对象和设备对象
当 I/O 管理器加载一个设备驱动程序时,它会创建一个驱动程序对象,该对象在对象管理器目录中的路径为:\Driver\<DriverName>或\FileSystem\<DriverName>。如果是文件系统类型的驱动程序,则该对象被放置在 "\FileSystem"目录下,否则放在"\Driver"目录下。因此,驱动程序可粗略地分为文件系统驱动程序和非文件系统驱动程序。 ...
【GlobalMapper精品教程】094:GlobalMapper26简体中文版安装教程(附安装包下载)
【GlobalMapper精品教程】094:GlobalMapper26简体中文版安装教程(附安装包下载)- 基于深度学习的图像分析工具,用于自动识别土地覆盖分类、建筑物提取和车辆检测。新的太阳阴影分析工具,用于计算加载地形和 3D 要素的阴影。新的 GENERATE_SHADOWS 脚本命令允许自动执行这些计算。新增点云模型关键点自动识别。能够在自动点云分析工具中保存和加载自定义创建的要素模型。改进了像素到点中各种潜在重叠图像中 GCP 的自动识别。
驱动开发:驱动与应用的通信
驱动程序与应用程序的通信离不开派遣函数,派遣函数是Windows驱动编程中的重要概念,一般情况下驱动程序负责处理I/O特权请求,而大部分IO的处理请求是在派遣函数中处理的,当用户请求数据时,操作系统会提前处理好请求,并将其派遣到指定的内核函数中执行,接下来将详细说明派遣函数的使用并通过派遣函数读取Shadow SSDT中的内容。先来简单介绍一下。
SAP B1中文培訓教材_SDK
公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说
老版QQ原生表情gif动态
这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。
驱动程序内存分配
何谓可分页和非分页内存 默认情况下,内核加载器会加载所有的代码部分和全局数据到非分页内存中。而且,加载器是一次加载整个驱动的可执行文件,包括相关的DLL。加载后,内核加载器关闭驱动程序文件,甚至你可以删除当前正在执行的驱动文件。但是,你可以告诉加载器你希望驱动的哪部分是可分页,所谓可分页,就是可能会被换页出内存(Page out)。可以使用下面的指令来实现:#define A
jre9下载 jdk9
(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】
Driver 加载步骤
Driver 加载步骤1)当硬件连接到PC或从PC移除时,在硬件上会有信号跳变,BUS Driver会检测到器件的插入和移除,比如DVI的hotplug,再比如USB1.1的1.5K上拉。BUS Driver将调用IOInvalidateDevcieRelations,PNP Manager将知道BUS上的Device关系有所改变。2)为了获得新的Device关系,PNP Manager将调用IRP
win10 跳过U8环境检测的IE WebControls.rar
win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。
IoCreateDevice简单分析
IoCreateDevice简单分析介绍大体流程存储参数扩展大小计算设备属性组计算判断设备属性组判断设备类型一些其他计算创建对象申请内存初始化设备队列插入对象传入模板 介绍 简单分析一下 大体流程 1.判断设备属性组 2.设备属性为0调用IopCreateDefaultDeviceSecurityDescriptor 3.判断设备类型 4.ObCreateObject 5.判断设备类型 6.FILE_DEVICE_UNKNOWN类型调用IopCreateVpb和KeInitializeEvent 7.KeI
【转载】分析重装系统也无法清除的鬼影病毒
原文:分析重装系统也无法清除的鬼影病毒 声明:本文由【MS509 Team】成员expsky原创,仅用于技术交流分享,禁止将相关技术应用到不当途径。 整理电脑的时候找到自已以前分析的一个鬼影病毒的资料,当时兼容市面上主要的windows系统(XP, win7,包含x86和x64系统)样本来自国外,有不少亮点,当时花了不少时间把所有原理分析出来并重新用汇编和C++实现了出来。以前的一些资料...
Do All In One EXE File Under Win32
文章提交:icelord (icelord_at_sohu.com)希望题目没有语法错误。 Exe可执行,可以使用系统提供的各种服务,do all in one exe看起来是句废话。仅作技术研究,各位不要为几个文字争论。很早就看过高手写过的文章,>、>,今天我也来班门弄斧一把。做后门、木马,现在的技术不知道是什么样的,但是个人认为将他们做到内核之中,将更有威力。当然,这也是把双刃剑。见过一
reactos操作系统实现(74)
很多驱动程序,都是通过硬件检测时写到注册表里保存起来的,因此读取注册表里键值列表,就知道有多少设备需要需要加载了。下面就从注册表里创建一组驱动程序列表,实现的代码如下: #001 NTSTATUS INIT_FUNCTION #002 IoCreateDriverList(VOID) #003 { #004 RTL_QUERY_REGISTRY_TABLE ...
《Windows NT File System Internals》学习笔记之物理内存管理简介
页帧和页帧数据库NT VMM必须管理系统内可用的物理内存。VMM使用的方法和现代商用操作系统中使用的方法类似。 NT VMM将可用的RAM划分为固定尺寸的页帧。页帧的大小可以从4K~64K。在Intel X86结构上,页尺寸为4K。每一个页桢都在页帧数据库(PFN Database)中有相应的入口项。页帧数据库在非分页内存池中,它是一个页帧入口数组。PFN数据库为每一个页帧维护以下信息
wdm 驱动 win7 无法加载_详解Windows渗透测试工具Mimikatz的内核驱动
一、概述Mimikatz通过其中包含的Mimidrv驱动程序,提供了利用内核模式的功能。Mimidrv是已经签名的Windows驱动模型(WDM)内核模式软件驱动程序,在相关命令前加上感叹号(!)即可与标准Mimikatz可执行文件共同使用。Mimidrv没有相应文档,并且很少被人使用,但它却提供了一个非常值得关注的方式,让我们可以在ring 0执行一些操作。本文详细分析Mimidrv...
关于ntoskrnl.exe蓝屏一些历程(不保证完全解决)
我之所以会发现这个问题,是因为我室友也有一台同样型号的r7000p,但是他的电脑稳定许多,所以我觉得下载安装上他的驱动,由于我之前的折腾我已经把显卡和BIOS驱动都安装了官网的win10版本64位驱动版本,win11使用起来并没问题,且与我室友的版本相同,只有nvidia usb type c port policy controller驱动这个版本相差极多,我之前的版本为1.1...极易蓝屏报错,更新到1.46后稳定了许多,因为联想电脑管家驱动无论多旧的版本都只会显示推荐,所以这个驱动很难更新上来。
hal!HaliInitPnpDriver函数分析之nt!IoCreateDriver之驱动对象=Driver=ACPI_HAL的两个设备对象怎么来的
hal!HaliInitPnpDriver函数分析之nt!IoCreateDriver之驱动对象=Driver=ACPI_HAL的两个设备对象怎么来的
由Win10系统ntoskrnl.exe引起电脑蓝屏几个解决参考
同时还显示是由ntoskrnl.exe引起,那么这个ntoskrnl.exe是什么,对于它引起的蓝屏问题,我们应该如何手动解决呢?ntoskenl 是 Windows 的内核进程,负责 Windows 核心部分的操作,也就是负责操作系统核心的五大任务:处理机管理、存储管理、设备管理、文件管理、接口,这从它的 PID = 4 就能看出来它的地位是操作系统最先启动的进程。下载这款文件后,扫描一下电脑缺少的重要系统组件,根据电脑确实的系统文件来修复系统问题。依次打开控制面板——>管理工具——>任务计划程序。
2505



被折叠的 条评论
为什么被折叠?



