`
yuanjinxiu
  • 浏览: 658974 次
文章分类
社区版块
存档分类
最新评论

reactos操作系统实现(87)

 
阅读更多

应用程序对设备I/O进行Win32调用,这个调用由I/O系统服务接收,然后I/O管理器从这个请求构造一个合适的I/O请求包(IRP)。那么I/O管理器是怎么样创建这个I/O请求包(IRP)的呢?又是怎么样传送给驱动程序的呢?我们带着这两个问题来分析下面实现文件读取的代码,如下:

#001 NTSTATUS

#002 NTAPI

#003 NtReadFile(IN HANDLE FileHandle,

#004 IN HANDLE Event OPTIONAL,

#005 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,

#006 IN PVOID ApcContext OPTIONAL,

#007 OUT PIO_STATUS_BLOCK IoStatusBlock,

#008 OUT PVOID Buffer,

#009 IN ULONG Length,

#010 IN PLARGE_INTEGER ByteOffset OPTIONAL,

#011 IN PULONG Key OPTIONAL)

#012 {

#013 NTSTATUS Status = STATUS_SUCCESS;

#014 PFILE_OBJECT FileObject;

#015 PIRP Irp;

#016 PDEVICE_OBJECT DeviceObject;

#017 PIO_STACK_LOCATION StackPtr;

#018 KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();

#019 PKEVENT EventObject = NULL;

#020 LARGE_INTEGER CapturedByteOffset;

#021 ULONG CapturedKey = 0;

#022 BOOLEAN Synchronous = FALSE;

#023 PMDL Mdl;

#024 PAGED_CODE();

#025 CapturedByteOffset.QuadPart = 0;

#026 IOTRACE(IO_API_DEBUG, "FileHandle: %p/n", FileHandle);

#027

检查是否在用户模式调用。

#028 /* Validate User-Mode Buffers */

#029 if(PreviousMode != KernelMode)

#030 {

使用SEH机制,以便截取异常。

#031 _SEH2_TRY

#032 {

检测状态块。

#033 /* Probe the status block */

#034 ProbeForWriteIoStatusBlock(IoStatusBlock);

#035

检查读取缓冲区。

#036 /* Probe the read buffer */

#037 ProbeForWrite(Buffer, Length, 1);

#038

#039 /* Check if we got a byte offset */

#040 if (ByteOffset)

#041 {

#042 /* Capture and probe it */

#043 CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);

#044 }

#045

#046 /* Capture and probe the key */

#047 if (Key) CapturedKey = ProbeForReadUlong(Key);

#048 }

#049 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

#050 {

#051 /* Get the exception code */

#052 Status = _SEH2_GetExceptionCode();

#053 }

#054 _SEH2_END;

#055

#056 /* Check for probe failure */

#057 if (!NT_SUCCESS(Status)) return Status;

#058 }

#059 else

#060 {

#061 /* Kernel mode: capture directly */

#062 if (ByteOffset) CapturedByteOffset = *ByteOffset;

#063 if (Key) CapturedKey = *Key;

#064 }

#065

获取文件对象。

#066 /* Get File Object */

#067 Status = ObReferenceObjectByHandle(FileHandle,

#068 FILE_READ_DATA,

#069 IoFileObjectType,

#070 PreviousMode,

#071 (PVOID*)&FileObject,

#072 NULL);

#073 if (!NT_SUCCESS(Status)) return Status;

#074

检查事件是否响应。

#075 /* Check for event */

#076 if (Event)

#077 {

#078 /* Reference it */

#079 Status = ObReferenceObjectByHandle(Event,

#080 EVENT_MODIFY_STATE,

#081 ExEventObjectType,

#082 PreviousMode,

#083 (PVOID*)&EventObject,

#084 NULL);

#085 if (!NT_SUCCESS(Status))

#086 {

#087 /* Fail */

#088 ObDereferenceObject(FileObject);

#089 return Status;

#090 }

#091

#092 /* Otherwise reset the event */

#093 KeClearEvent(EventObject);

#094 }

#095

检查是否使用同步I/O的方式。

#096 /* Check if we should use Sync IO or not */

#097 if (FileObject->Flags & FO_SYNCHRONOUS_IO)

#098 {

这里是使用同步模式。

#099 /* Lock the file object */

#100 IopLockFileObject(FileObject);

#101

#102 /* Check if we don't have a byte offset avilable */

#103 if (!(ByteOffset) ||

#104 ((CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION) &&

#105 (CapturedByteOffset.u.HighPart == -1)))

#106 {

#107 /* Use the Current Byte Offset instead */

#108 CapturedByteOffset = FileObject->CurrentByteOffset;

#109 }

#110

#111 /* Remember we are sync */

#112 Synchronous = TRUE;

#113 }

#114 else if (!(ByteOffset) &&

#115 !(FileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT)))

#116 {

非法文件对象。

#117 /* Otherwise, this was async I/O without a byte offset, so fail */

#118 if (EventObject) ObDereferenceObject(EventObject);

#119 ObDereferenceObject(FileObject);

#120 return STATUS_INVALID_PARAMETER;

#121 }

#122

从文件里获取设备对象。

#123 /* Get the device object */

#124 DeviceObject = IoGetRelatedDeviceObject(FileObject);

#125

#126 /* Clear the File Object's event */

#127 KeClearEvent(&FileObject->Event);

#128

分配一个读取文件的请求包(IRP)。

#129 /* Allocate the IRP */

#130 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);

#131 if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);

#132

设置IRP的属性。

#133 /* Set the IRP */

#134 Irp->Tail.Overlay.OriginalFileObject = FileObject;

#135 Irp->Tail.Overlay.Thread = PsGetCurrentThread();

#136 Irp->RequestorMode = PreviousMode;

#137 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;

#138 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;

#139 Irp->UserIosb = IoStatusBlock;

#140 Irp->UserEvent = EventObject;

#141 Irp->PendingReturned = FALSE;

#142 Irp->Cancel = FALSE;

#143 Irp->CancelRoutine = NULL;

#144 Irp->AssociatedIrp.SystemBuffer = NULL;

#145 Irp->MdlAddress = NULL;

#146

设置IRP的调用栈。

#147 /* Set the Stack Data */

#148 StackPtr = IoGetNextIrpStackLocation(Irp);

#149 StackPtr->MajorFunction = IRP_MJ_READ;

#150 StackPtr->FileObject = FileObject;

#151 StackPtr->Parameters.Read.Key = CapturedKey;

#152 StackPtr->Parameters.Read.Length = Length;

#153 StackPtr->Parameters.Read.ByteOffset = CapturedByteOffset;

#154

检查设备对象是否使用缓冲I/O的方式,还是使用直接I/O的方式。

#155 /* Check if this is buffered I/O */

#156 if (DeviceObject->Flags & DO_BUFFERED_IO)

#157 {

使用缓冲I/O的方式,就分配非分页内存。

#158 /* Check if we have a buffer length */

#159 if (Length)

#160 {

#161 /* Enter SEH */

#162 _SEH2_TRY

#163 {

#164 /* Allocate a buffer */

#165 Irp->AssociatedIrp.SystemBuffer =

#166 ExAllocatePoolWithTag(NonPagedPool,

#167 Length,

#168 TAG_SYSB);

#169 }

#170 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

#171 {

#172 /* Allocating failed, clean up */

#173 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);

#174 Status = _SEH2_GetExceptionCode();

#175 }

#176 _SEH2_END;

#177 if (!NT_SUCCESS(Status)) return Status;

#178

#179 /* Set the buffer and flags */

#180 Irp->UserBuffer = Buffer;

#181 Irp->Flags = (IRP_BUFFERED_IO |

#182 IRP_DEALLOCATE_BUFFER |

#183 IRP_INPUT_OPERATION);

#184 }

#185 else

#186 {

#187 /* Not reading anything */

#188 Irp->Flags = IRP_BUFFERED_IO | IRP_INPUT_OPERATION;

#189 }

#190 }

#191 else if (DeviceObject->Flags & DO_DIRECT_IO)

#192 {

使用直接I/O的方式,就创建内存描述符列表。

#193 /* Check if we have a buffer length */

#194 if (Length)

#195 {

#196 _SEH2_TRY

#197 {

#198 /* Allocate an MDL */

#199 Mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, Irp);

#200 MmProbeAndLockPages(Mdl, PreviousMode, IoWriteAccess);

#201 }

#202 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

#203 {

#204 /* Allocating failed, clean up */

#205 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);

#206 Status = _SEH2_GetExceptionCode();

#207 _SEH2_YIELD(return Status);

#208 }

#209 _SEH2_END;

#210

#211 }

#212

#213 /* No allocation flags */

#214 Irp->Flags = 0;

#215 }

#216 else

#217 {

#218 /* No allocation flags, and use the buffer directly */

#219 Irp->Flags = 0;

#220 Irp->UserBuffer = Buffer;

#221 }

#222

设置读取的标志。

#223 /* Now set the deferred read flags */

#224 Irp->Flags |= (IRP_READ_OPERATION | IRP_DEFER_IO_COMPLETION);

#225 #if 0

#226 /* FIXME: VFAT SUCKS */

#227 if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;

#228 #endif

#229

调用函数IopPerformSynchronousRequestIRP发送给过滤驱动程序,或者目标驱动程序。

#230 /* Perform the call */

#231 return IopPerformSynchronousRequest(DeviceObject,

#232 Irp,

#233 FileObject,

#234 TRUE,

#235 PreviousMode,

#236 Synchronous,

#237 IopReadTransfer);

#238 }

#239

下面继续分析写文件的操作函数,就可以知道写文件时怎么样发送I/O请求包,实现代码如下:

#001 NTSTATUS

#002 NTAPI

#003 NtWriteFile(IN HANDLE FileHandle,

#004 IN HANDLE Event OPTIONAL,

#005 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,

#006 IN PVOID ApcContext OPTIONAL,

#007 OUT PIO_STATUS_BLOCK IoStatusBlock,

#008 IN PVOID Buffer,

#009 IN ULONG Length,

#010 IN PLARGE_INTEGER ByteOffset OPTIONAL,

#011 IN PULONG Key OPTIONAL)

#012 {

#013 NTSTATUS Status = STATUS_SUCCESS;

#014 PFILE_OBJECT FileObject;

#015 PIRP Irp;

#016 PDEVICE_OBJECT DeviceObject;

#017 PIO_STACK_LOCATION StackPtr;

获取前一个内核模式。

#018 KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();

#019 PKEVENT EventObject = NULL;

#020 LARGE_INTEGER CapturedByteOffset;

#021 ULONG CapturedKey = 0;

#022 BOOLEAN Synchronous = FALSE;

#023 PMDL Mdl;

#024 OBJECT_HANDLE_INFORMATION ObjectHandleInfo;

#025 PAGED_CODE();

#026 CapturedByteOffset.QuadPart = 0;

#027 IOTRACE(IO_API_DEBUG, "FileHandle: %p/n", FileHandle);

#028

获取文件对象。

#029 /* Get File Object */

#030 Status = ObReferenceObjectByHandle(FileHandle,

#031 0,

#032 IoFileObjectType,

#033 PreviousMode,

#034 (PVOID*)&FileObject,

#035 &ObjectHandleInfo);

#036 if (!NT_SUCCESS(Status)) return Status;

#037

检查是否用户模式调用,如果是就需要使用SEH机制。

#038 /* Validate User-Mode Buffers */

#039 if(PreviousMode != KernelMode)

#040 {

#041 _SEH2_TRY

#042 {

检查是否有写文件的权限。

#043 /*

#044 * Check if the handle has either FILE_WRITE_DATA or

#045 * FILE_APPEND_DATA granted. However, if this is a named pipe,

#046 * make sure we don't ask for FILE_APPEND_DATA as it interferes

#047 * with the FILE_CREATE_PIPE_INSTANCE access right!

#048 */

#049 if (!(ObjectHandleInfo.GrantedAccess &

#050 ((!(FileObject->Flags & FO_NAMED_PIPE) ?

#051 FILE_APPEND_DATA : 0) | FILE_WRITE_DATA)))

#052 {

#053 /* We failed */

#054 ObDereferenceObject(FileObject);

#055 _SEH2_YIELD(return STATUS_ACCESS_DENIED);

#056 }

#057

获取状态代码块。

#058 /* Probe the status block */

#059 ProbeForWriteIoStatusBlock(IoStatusBlock);

#060

#061 /* Probe the read buffer */

#062 ProbeForRead(Buffer, Length, 1);

#063

#064 /* Check if we got a byte offset */

#065 if (ByteOffset)

#066 {

#067 /* Capture and probe it */

#068 CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);

#069 }

#070

#071 /* Capture and probe the key */

#072 if (Key) CapturedKey = ProbeForReadUlong(Key);

#073 }

#074 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

#075 {

#076 /* Get the exception code */

#077 Status = _SEH2_GetExceptionCode();

#078 }

#079 _SEH2_END;

#080

#081 /* Check for probe failure */

#082 if (!NT_SUCCESS(Status)) return Status;

#083 }

#084 else

#085 {

#086 /* Kernel mode: capture directly */

#087 if (ByteOffset) CapturedByteOffset = *ByteOffset;

#088 if (Key) CapturedKey = *Key;

#089 }

#090

检查是否为追加的模式。

#091 /* Check if this is an append operation */

#092 if ((ObjectHandleInfo.GrantedAccess &

#093 (FILE_APPEND_DATA | FILE_WRITE_DATA)) == FILE_APPEND_DATA)

#094 {

#095 /* Give the drivers something to understand */

#096 CapturedByteOffset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;

#097 CapturedByteOffset.u.HighPart = -1;

#098 }

#099

检查是否使用事件。

#100 /* Check for event */

#101 if (Event)

#102 {

#103 /* Reference it */

#104 Status = ObReferenceObjectByHandle(Event,

#105 EVENT_MODIFY_STATE,

#106 ExEventObjectType,

#107 PreviousMode,

#108 (PVOID*)&EventObject,

#109 NULL);

#110 if (!NT_SUCCESS(Status))

#111 {

#112 /* Fail */

#113 ObDereferenceObject(FileObject);

#114 return Status;

#115 }

#116

清空事件。

#117 /* Otherwise reset the event */

#118 KeClearEvent(EventObject);

#119 }

#120

检查是否使用同步I/O的方式。

#121 /* Check if we should use Sync IO or not */

#122 if (FileObject->Flags & FO_SYNCHRONOUS_IO)

#123 {

#124 /* Lock the file object */

#125 IopLockFileObject(FileObject);

#126

#127 /* Check if we don't have a byte offset avilable */

#128 if (!(ByteOffset) ||

#129 ((CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION) &&

#130 (CapturedByteOffset.u.HighPart == -1)))

#131 {

#132 /* Use the Current Byte Offset instead */

#133 CapturedByteOffset = FileObject->CurrentByteOffset;

#134 }

#135

#136 /* Remember we are sync */

#137 Synchronous = TRUE;

#138 }

#139 else if (!(ByteOffset) &&

#140 !(FileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT)))

#141 {

#142 /* Otherwise, this was async I/O without a byte offset, so fail */

#143 if (EventObject) ObDereferenceObject(EventObject);

#144 ObDereferenceObject(FileObject);

#145 return STATUS_INVALID_PARAMETER;

#146 }

#147

获取文件对应的设备对象。

#148 /* Get the device object */

#149 DeviceObject = IoGetRelatedDeviceObject(FileObject);

#150

#151 /* Clear the File Object's event */

#152 KeClearEvent(&FileObject->Event);

#153

分配一个请求包(IRP)。

#154 /* Allocate the IRP */

#155 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);

#156 if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);

#157

设置IRP的属性。

#158 /* Set the IRP */

#159 Irp->Tail.Overlay.OriginalFileObject = FileObject;

#160 Irp->Tail.Overlay.Thread = PsGetCurrentThread();

#161 Irp->RequestorMode = PreviousMode;

#162 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;

#163 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;

#164 Irp->UserIosb = IoStatusBlock;

#165 Irp->UserEvent = EventObject;

#166 Irp->PendingReturned = FALSE;

#167 Irp->Cancel = FALSE;

#168 Irp->CancelRoutine = NULL;

#169 Irp->AssociatedIrp.SystemBuffer = NULL;

#170 Irp->MdlAddress = NULL;

#171

设置与IRP一致的栈空间。

#172 /* Set the Stack Data */

#173 StackPtr = IoGetNextIrpStackLocation(Irp);

#174 StackPtr->MajorFunction = IRP_MJ_WRITE;

#175 StackPtr->FileObject = FileObject;

#176 StackPtr->Flags = FileObject->Flags & FO_WRITE_THROUGH ?

#177 SL_WRITE_THROUGH : 0;

#178 StackPtr->Parameters.Write.Key = CapturedKey;

#179 StackPtr->Parameters.Write.Length = Length;

#180 StackPtr->Parameters.Write.ByteOffset = CapturedByteOffset;

#181

检查是否使用缓冲I/O的方式。

#182 /* Check if this is buffered I/O */

#183 if (DeviceObject->Flags & DO_BUFFERED_IO)

#184 {

#185 /* Check if we have a buffer length */

#186 if (Length)

#187 {

#188 /* Enter SEH */

#189 _SEH2_TRY

#190 {

#191 /* Allocate a buffer */

#192 Irp->AssociatedIrp.SystemBuffer =

#193 ExAllocatePoolWithTag(NonPagedPool,

#194 Length,

#195 TAG_SYSB);

#196

#197 /* Copy the data into it */

#198 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);

#199 }

#200 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

#201 {

#202 /* Allocating failed, clean up */

#203 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);

#204 Status = _SEH2_GetExceptionCode();

#205 _SEH2_YIELD(return Status);

#206 }

#207 _SEH2_END;

#208

#209 /* Set the flags */

#210 Irp->Flags = (IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);

#211 }

#212 else

#213 {

#214 /* Not writing anything */

#215 Irp->Flags = IRP_BUFFERED_IO;

#216 }

#217 }

#218 else if (DeviceObject->Flags & DO_DIRECT_IO)

#219 {

这里使用直接I/O的模式,因此调用IoAllocateMdl来创建内存描述符表。

#220 /* Check if we have a buffer length */

#221 if (Length)

#222 {

#223 _SEH2_TRY

#224 {

#225 /* Allocate an MDL */

#226 Mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, Irp);

#227 MmProbeAndLockPages(Mdl, PreviousMode, IoReadAccess);

#228 }

#229 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

#230 {

#231 /* Allocating failed, clean up */

#232 IopCleanupAfterException(FileObject, Irp, EventObject, NULL);

#233 Status = _SEH2_GetExceptionCode();

#234 _SEH2_YIELD(return Status);

#235 }

#236 _SEH2_END;

#237 }

#238

#239 /* No allocation flags */

#240 Irp->Flags = 0;

#241 }

#242 else

#243 {

#244 /* No allocation flags, and use the buffer directly */

#245 Irp->Flags = 0;

#246 Irp->UserBuffer = Buffer;

#247 }

#248

#249 /* Now set the deferred read flags */

#250 Irp->Flags |= (IRP_WRITE_OPERATION | IRP_DEFER_IO_COMPLETION);

#251 #if 0

#252 /* FIXME: VFAT SUCKS */

#253 if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;

#254 #endif

#255

调用函数IopPerformSynchronousRequest来分IRP请求包给相应的驱动程序。

#256 /* Perform the call */

#257 return IopPerformSynchronousRequest(DeviceObject,

#258 Irp,

#259 FileObject,

#260 TRUE,

#261 PreviousMode,

#262 Synchronous,

#263 IopWriteTransfer);

#264 }

分享到:
评论

相关推荐

    ReactOS-0.4.13-release-14-g2494cfc-iso.zip

    ReactOS项目致力于为大家开发一个免费而且完全兼容 Microsoft Windows XP 的操作系统。ReactOS 旨在通过使用类似构架和提供完整公共接口实现与 NT 以及 XP 操作系统二进制下的应用程序和驱动设备的完全兼容。 ...

    Windows 内核情景分析--采用开源代码ReactOS (上册) part02

    本书通过分析ReactOS的源代码介绍了Windows内核各个方面的结构、功能、算法与具体实现。全书从“内存管理”、“进程”、“进程间通信”、“设备驱动”等多个方面进行分析介绍,所有的分析都有ReactOS的源代码(以及...

    Windows 内核情景分析--采用开源代码ReactOS (上册) part01

    本书通过分析ReactOS的源代码介绍了Windows内核各个方面的结构、功能、算法与具体实现。全书从“内存管理”、“进程”、“进程间通信”、“设备驱动”等多个方面进行分析介绍,所有的分析都有ReactOS的源代码(以及...

    JS-OS:Web上的统一操作系统

    JS操作系统 Web上的统一操作系统。 使用的技术: HTML CSS JavaScript React-JS 如何在本地运行: 克隆仓库git clone https://github.com/NJACKWinterOfCode/JS-OS.git 进入JS-OS光盘进入JS-OS cd JS-OS 安装...

    漫谈兼容内核.zip

    漫谈兼容内核之一:ReactOS怎样实现系统调用 漫谈兼容内核之二:关于kernel-win32的对象管理 漫谈兼容内核之三:Kernel-win32的文件操作 漫谈兼容内核之四:Kernel-win32的进程管理 漫谈兼容内核之五:Kernel-win32...

    LKM-光纤:高级操作系统和虚拟化项目(20172018)课程在罗马大学萨皮恩扎市举行

    在本文档中,我们以Windows NT和ReactOS提供的Fibers实现为参考,介绍了可加载内核模块(LKM)实现。 虽然用户空间实现通常因其开销少且易于调试而成为首选,但是内核空间实现允许更深入地了解内核子系统的工作方式...

    漫谈Linux兼容内核

    01:ReactOS怎样实现系统调用.pdf 02:关于kernel -win32的对象管理.pdf 03:关于kernel-win32的文件操作.pdf 04:Kernel-win32的进程管理.pdf 05:Kernel-win32的系统调用机制.pdf 06:二进制映像的类型识别.pdf 07...

    harmonyos2-reactive-extra:流星React额外包

    React式对象实现。 结帐 用法 var obj = new ReactiveObject ( { 'foo' : '1' } ) ; obj . defineProperty ( 'bar' , 2 ) ; obj . foo = '2' ; obj . undefineProperty ( 'foo' ) ; // Don't use 'delete obj.foo' ...

    DLL注入之远线程方式

    远线程注入 每个进程都有自己的虚拟地址空间,对32位进程来说,这个地址空间的大小为4GB。...如下摘自ReactOS 3.14的代码所示,CreateRemoteThread实际实现的功能就是调用NtCreateThread创建一个属于目标进程的线程。

    Windows之漫谈兼容内核

    漫谈兼容内核之一:ReactOS怎样实现系统调用 漫谈兼容内核之二:关于kernel-win32的对象管理 漫谈兼容内核之三:Kernel-win32的文件操作 漫谈兼容内核之四:Kernel-win32的进程管理 漫谈兼容内核之五:Kernel-win32...

    winampify::high_voltage:具有操作系统外观的界面和经典音频播放器Winamp的重新实现的Spotify Web客户端

    艺术家,专辑和曲目都以文件和文件夹的形式呈现,并且可以在Winamp重新实现轻松地进行操作和播放。现场环境动机构建软件应该保持乐趣。 这个项目主要是一个沙箱,我可以尝试并提高对React和TypeScript的了解。 这也...

    CredBandit

    内存转储是通过使用NTFS事务完成的,NTFS事务使我们可以将转储写入内存,并且MiniDumpWriteDump API已被ReactOS的MiniDumpWriteDump实现改编所取代。 然后,BOF使用base64对内存中的数据进行编码,将其分块,然后...

    React Native 的 UIDevice 类包装器

    isIpad() 设备型号为 iPad Device.isIphone() 设备型号为 iPhone Properties Device.model 设备型号,如 iPhone 或 iPad Device.deviceName 设备名称,如 John Smith 的 iPhone Device.systemName设备操作系统名称...

    漫谈兼容内核.7z

    谈兼容内核之一:ReactOS怎样实现系统调用.pdf 漫谈兼容内核之二:关于kernel -win32的对象管理.pdf 漫谈兼容内核之三:关于kernel-win32的文件操作.pdf 漫谈兼容内核之四:Kernel-win32的进程管理.pdf 漫谈兼容内核...

    phoebe:菲比

    在许多情况下,操作员习惯于处理遥测,实时图表,警报等,这可以帮助他们确定有问题的机器并做出React以解决任何潜在的问题。 但是,一个问题浮现在脑海:如果机器可以自动调整自身并为用户提供自我修复功能,那...

    hyperglass:超级玻璃是试图使互联网变得更好的网络外观玻璃

    功能,主题,UI / API文本,错误消息,命令内置支持: Arista EOS 鸟思科IOS-XR 思科IOS / IOS-XE 思科NX-OS FRRouting 了华为瞻博JunOS 米克罗蒂克诺基亚SR OS TNSR 虚拟操作系统对任何其他配置支持(可选)通过SSH...

    sentinel-crawler:Xenomorph Crawler, a Concise, Declarative and Observable Distributed Crawler(Node Go Java Rust) For Web, RDB, OS, also can act as a Monitor(with Prometheus) or ETL for Infrastructure 多语言执行器,分布式爬虫

    xe-crawlerxe-crawler 是遵循声明式、可监测理念的分布式爬虫,其计划提供 Node.js、Go、Python 多种实现,能够对于静态 Web 页面、动态 Web 页面、关系型数据库、操作系统等异构多源数据进行抓取。xe-crawler 希望...

    图像dct变换matlab代码-SJTU-IE307-hw1:ConductedbyProf.XieRong

    实现分块功能可以采用手动循环的对每个块依次操作,也可以使用Matlab提供的分块处理功能blkproc。 选择两张大小相同的图像,分别进行DFT变换后,置换两幅图像的幅度和相位信息后再作反变换,观察并分析结果。 主要...

Global site tag (gtag.js) - Google Analytics