- 浏览: 658974 次
文章分类
最新评论
-
ranweizheng:
看了lz的文章感慨颇多啊,说的很对哈。顺便炫耀下,来现在的公司 ...
程序员都应该知道的福利 -
anttu:
...
Request 对象 -
tianlovv:
恩,不错,楼主细心
整理电脑里面的前端开发中的小Tips【及时更新】 -
forcer521:
楼主非常有经验啊
程序员都应该知道的福利 -
forcer521:
不错,非常有用处啊!
整理电脑里面的前端开发中的小Tips【及时更新】
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
调用函数IopPerformSynchronousRequest把IRP发送给过滤驱动程序,或者目标驱动程序。
#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项目致力于为大家开发一个免费而且完全兼容 Microsoft Windows XP 的操作系统。ReactOS 旨在通过使用类似构架和提供完整公共接口实现与 NT 以及 XP 操作系统二进制下的应用程序和驱动设备的完全兼容。 ...
本书通过分析ReactOS的源代码介绍了Windows内核各个方面的结构、功能、算法与具体实现。全书从“内存管理”、“进程”、“进程间通信”、“设备驱动”等多个方面进行分析介绍,所有的分析都有ReactOS的源代码(以及...
本书通过分析ReactOS的源代码介绍了Windows内核各个方面的结构、功能、算法与具体实现。全书从“内存管理”、“进程”、“进程间通信”、“设备驱动”等多个方面进行分析介绍,所有的分析都有ReactOS的源代码(以及...
JS操作系统 Web上的统一操作系统。 使用的技术: HTML CSS JavaScript React-JS 如何在本地运行: 克隆仓库git clone https://github.com/NJACKWinterOfCode/JS-OS.git 进入JS-OS光盘进入JS-OS cd JS-OS 安装...
漫谈兼容内核之一:ReactOS怎样实现系统调用 漫谈兼容内核之二:关于kernel-win32的对象管理 漫谈兼容内核之三:Kernel-win32的文件操作 漫谈兼容内核之四:Kernel-win32的进程管理 漫谈兼容内核之五:Kernel-win32...
在本文档中,我们以Windows NT和ReactOS提供的Fibers实现为参考,介绍了可加载内核模块(LKM)实现。 虽然用户空间实现通常因其开销少且易于调试而成为首选,但是内核空间实现允许更深入地了解内核子系统的工作方式...
01:ReactOS怎样实现系统调用.pdf 02:关于kernel -win32的对象管理.pdf 03:关于kernel-win32的文件操作.pdf 04:Kernel-win32的进程管理.pdf 05:Kernel-win32的系统调用机制.pdf 06:二进制映像的类型识别.pdf 07...
React式对象实现。 结帐 用法 var obj = new ReactiveObject ( { 'foo' : '1' } ) ; obj . defineProperty ( 'bar' , 2 ) ; obj . foo = '2' ; obj . undefineProperty ( 'foo' ) ; // Don't use 'delete obj.foo' ...
远线程注入 每个进程都有自己的虚拟地址空间,对32位进程来说,这个地址空间的大小为4GB。...如下摘自ReactOS 3.14的代码所示,CreateRemoteThread实际实现的功能就是调用NtCreateThread创建一个属于目标进程的线程。
漫谈兼容内核之一:ReactOS怎样实现系统调用 漫谈兼容内核之二:关于kernel-win32的对象管理 漫谈兼容内核之三:Kernel-win32的文件操作 漫谈兼容内核之四:Kernel-win32的进程管理 漫谈兼容内核之五:Kernel-win32...
艺术家,专辑和曲目都以文件和文件夹的形式呈现,并且可以在Winamp重新实现轻松地进行操作和播放。现场环境动机构建软件应该保持乐趣。 这个项目主要是一个沙箱,我可以尝试并提高对React和TypeScript的了解。 这也...
内存转储是通过使用NTFS事务完成的,NTFS事务使我们可以将转储写入内存,并且MiniDumpWriteDump API已被ReactOS的MiniDumpWriteDump实现改编所取代。 然后,BOF使用base64对内存中的数据进行编码,将其分块,然后...
isIpad() 设备型号为 iPad Device.isIphone() 设备型号为 iPhone Properties Device.model 设备型号,如 iPhone 或 iPad Device.deviceName 设备名称,如 John Smith 的 iPhone Device.systemName设备操作系统名称...
谈兼容内核之一:ReactOS怎样实现系统调用.pdf 漫谈兼容内核之二:关于kernel -win32的对象管理.pdf 漫谈兼容内核之三:关于kernel-win32的文件操作.pdf 漫谈兼容内核之四:Kernel-win32的进程管理.pdf 漫谈兼容内核...
在许多情况下,操作员习惯于处理遥测,实时图表,警报等,这可以帮助他们确定有问题的机器并做出React以解决任何潜在的问题。 但是,一个问题浮现在脑海:如果机器可以自动调整自身并为用户提供自我修复功能,那...
功能,主题,UI / API文本,错误消息,命令内置支持: Arista EOS 鸟思科IOS-XR 思科IOS / IOS-XE 思科NX-OS FRRouting 了华为瞻博JunOS 米克罗蒂克诺基亚SR OS TNSR 虚拟操作系统对任何其他配置支持(可选)通过SSH...
xe-crawlerxe-crawler 是遵循声明式、可监测理念的分布式爬虫,其计划提供 Node.js、Go、Python 多种实现,能够对于静态 Web 页面、动态 Web 页面、关系型数据库、操作系统等异构多源数据进行抓取。xe-crawler 希望...
实现分块功能可以采用手动循环的对每个块依次操作,也可以使用Matlab提供的分块处理功能blkproc。 选择两张大小相同的图像,分别进行DFT变换后,置换两幅图像的幅度和相位信息后再作反变换,观察并分析结果。 主要...