mrkrcl 发表于 2012-2-3 13:34:28

某段直接从磁盘读取文件的源码

NTSTATUS GetFileVolumeHandle(
   IN UNICODE_STRING *NativePath,
   OUT HANDLE *VolumeHandle)
{
   NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;

   WCHAR VolumeLetter;

   UNICODE_STRING VolumeName;
   OBJECT_ATTRIBUTES ObjectAttributes = {0};
    IO_STATUS_BLOCK IoStatusBlock;


   __try
   {
      if(NativePath == NULL)
         return STATUS_INVALID_PARAMETER_1;

      if(NativePath->Buffer == NULL ||
         NativePath->Length == 0)
      {
         return STATUS_INVALID_PARAMETER_1;
      }

      if(VolumeHandle == NULL)
         return STATUS_INVALID_PARAMETER_2;

      if(NativePath->Buffer != L'\\' ||
         NativePath->Buffer != L'?'||
         NativePath->Buffer != L'?'||
         NativePath->Buffer != L'\\' ||
         NativePath->Buffer != L':')
      {
         return STATUS_OBJECT_PATH_SYNTAX_BAD;
      }

      *VolumeHandle = NULL;


      RtlZeroMemory(
               VolumeLetter,
               sizeof(VolumeLetter));
      
      NtStatus = StringCchPrintfW(
                           VolumeLetter,
                           sizeof(VolumeLetter),
                           L"\\??\\%c:",
                           NativePath->Buffer);

      if(SUCCEEDED(NtStatus))
      {
         RtlInitUnicodeString(
                         &VolumeName,
                         VolumeLetter);

         ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
         ObjectAttributes.ObjectName = &VolumeName;
         ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
      
         NtStatus = NtCreateFile(
                           VolumeHandle,      // FileHandle
                           GENERIC_READ |
                           GENERIC_WRITE,   // DesiredAccess
                           &ObjectAttributes, // ObjectAttributes
                           &IoStatusBlock,    // IoStatusBlock
                           NULL,            // AllocationSize OPTIONAL
                           0,               // FileAttributes
                           FILE_SHARE_READ |
                           FILE_SHARE_WRITE,// ShareAccess
                           FILE_OPEN,         // CreateDisposition
                           0,               // CreateOptions
                           NULL,            // EaBuffer OPTIONAL
                           0);                // EaLength

         if(NtStatus)
         {
            DbgPrint((
                  ">> GetFileVolumeHandle - NtCreateFile - %.8X\n",
                  NtStatus));
         }
      }
   }
    __except(GetExceptionCode() ==
          EXCEPTION_BREAKPOINT ?
          EXCEPTION_CONTINUE_SEARCH :
          EXCEPTION_EXECUTE_HANDLER)
    {
      DbgPrint((
            ">> GetFileVolumeHandle - %.8X\n",
            GetExceptionCode()));

      return GetExceptionCode();
    }

    return NtStatus;
}

NTSTATUS GetFilePhysicalOffset(
   IN UNICODE_STRING *NativePath,
   OUT LONGLONG *PhysicalOffset)
{
   NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;

   HANDLE FileHandle;
   HANDLE VolumeHandle;
   ULONG RetrievalPointersLength = PAGE_SIZE;

   OBJECT_ATTRIBUTES ObjectAttributes = {0};
    IO_STATUS_BLOCK IoStatusBlock;

   STARTING_VCN_INPUT_BUFFER StartingVcn = {0};
   RETRIEVAL_POINTERS_BUFFER *RetrievalPointers = NULL;
   NTFS_VOLUME_DATA_BUFFER VolumeData;
   VOLUME_LOGICAL_OFFSET VolumeLogicalOffset;
   VOLUME_PHYSICAL_OFFSETS VolumePhysicalOffsets;
   

   __try
   {
      if(NativePath == NULL)
         return STATUS_INVALID_PARAMETER_1;

      if(NativePath->Buffer == NULL ||
         NativePath->Length == 0)
      {
         return STATUS_INVALID_PARAMETER_1;
      }

      if(PhysicalOffset == NULL)
         return STATUS_INVALID_PARAMETER_2;

      if(NativePath->Buffer != L'\\' ||
         NativePath->Buffer != L'?'||
         NativePath->Buffer != L'?'||
         NativePath->Buffer != L'\\' ||
         NativePath->Buffer != L':')
      {
         return STATUS_OBJECT_PATH_SYNTAX_BAD;
      }

      *PhysicalOffset = 0;


      ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
      ObjectAttributes.ObjectName = NativePath;
      ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
      
      NtStatus = NtCreateFile(
                        &FileHandle,       // FileHandle
                        GENERIC_READ |
                        GENERIC_WRITE,   // DesiredAccess
                        &ObjectAttributes, // ObjectAttributes
                        &IoStatusBlock,    // IoStatusBlock
                        NULL,            // AllocationSize OPTIONAL
                        0,               // FileAttributes
                        FILE_SHARE_READ |
                        FILE_SHARE_WRITE,// ShareAccess
                        FILE_OPEN,         // CreateDisposition
                        0,               // CreateOptions
                        NULL,            // EaBuffer OPTIONAL
                        0);                // EaLength

      if(NtStatus)
      {
         DbgPrint((
               ">> GetFilePhysicalOffset - NtCreateFile - %.8X\n",
               NtStatus));
      }

      if(NT_SUCCESS(NtStatus))
      {
         do
         {
            RetrievalPointers = RtlAllocateMemory(RetrievalPointersLength);

            if(RetrievalPointers)
            {
               NtStatus = NtFsControlFile(
                                    FileHandle,                        // FileHandle
                                    NULL,                              // Event
                                    NULL,                              // ApcRoutine
                                    NULL,                              // ApcContext
                                    &IoStatusBlock,                  // IoStatusBlock
                                    FSCTL_GET_RETRIEVAL_POINTERS,      // FsControlCode
                                    &StartingVcn,                      // InputBuffer
                                    sizeof(STARTING_VCN_INPUT_BUFFER), // InputBufferLength
                                    RetrievalPointers,               // OutputBuffer
                                    RetrievalPointersLength);          // OutputBufferLength
                  
               if(NtStatus == STATUS_INFO_LENGTH_MISMATCH)
               {
                  RtlFreeMemory(RetrievalPointers);

                  RetrievalPointersLength *= 2;
               }
               else if(NT_ERROR(NtStatus))
               {
                  DbgPrint((
                        ">> GetFilePhysicalOffset - FSCTL_GET_RETRIEVAL_POINTERS - %.8X\n",
                        NtStatus));

                  RtlFreeMemory(RetrievalPointers);

                  NtClose(FileHandle);

                  return NtStatus;
               }
            }
            else
            {
               NtClose(FileHandle);

               return STATUS_INSUFFICIENT_RESOURCES;
            }

         } while(NtStatus == STATUS_INFO_LENGTH_MISMATCH);

         NtStatus = GetFileVolumeHandle(
                                  NativePath,   // NativePath
                                  &VolumeHandle); // VolumeHandle

         if(NT_SUCCESS(NtStatus))
         {
            NtStatus = NtFsControlFile(
                                 VolumeHandle,                     // FileHandle
                                 NULL,                           // Event
                                 NULL,                           // ApcRoutine
                                 NULL,                           // ApcContext
                                 &IoStatusBlock,                   // IoStatusBlock
                                 FSCTL_GET_NTFS_VOLUME_DATA,       // FsControlCode
                                 NULL,                           // InputBuffer
                                 0,                              // InputBufferLength
                                 &VolumeData,                      // OutputBuffer
                                 sizeof(NTFS_VOLUME_DATA_BUFFER)); // OutputBufferLength

            if(NtStatus)
            {
               DbgPrint((
                     ">> GetFilePhysicalOffset - FSCTL_GET_NTFS_VOLUME_DATA - %.8X\n",
                     NtStatus));
            }

            if(NT_SUCCESS(NtStatus))
            {
               VolumeLogicalOffset.LogicalOffset = RetrievalPointers->Extents.Lcn.QuadPart *
                                          VolumeData.BytesPerCluster;

               NtStatus = NtDeviceIoControlFile(
                                        VolumeHandle,                     // FileHandle
                                        NULL,                           // Event
                                        NULL,                           // ApcRoutine
                                        NULL,                           // ApcContext
                                        &IoStatusBlock,                   // IoStatusBlock
                                        IOCTL_VOLUME_LOGICAL_TO_PHYSICAL, // IoControlCode
                                        &VolumeLogicalOffset,             // InputBuffer
                                        sizeof(VOLUME_LOGICAL_OFFSET),    // InputBufferLength
                                        &VolumePhysicalOffsets,         // OutputBuffer
                                        sizeof(VOLUME_PHYSICAL_OFFSETS)); // OutputBufferLength

               if(NtStatus)
               {
                  DbgPrint((
                        ">> GetFilePhysicalOffset - IOCTL_VOLUME_LOGICAL_TO_PHYSICAL - %.8X\n",
                        NtStatus));
               }

               if(NT_SUCCESS(NtStatus))
               {
                  *PhysicalOffset = (LONGLONG)(VolumePhysicalOffsets.PhysicalOffset.Offset /
                                        VolumeData.BytesPerSector);
               }
            }

            NtClose(VolumeHandle);
         }

         NtClose(FileHandle);

         RtlFreeMemory(RetrievalPointers);
      }
    }
    __except(GetExceptionCode() ==
          EXCEPTION_BREAKPOINT ?
          EXCEPTION_CONTINUE_SEARCH :
          EXCEPTION_EXECUTE_HANDLER)
    {
      if(FileHandle)
         NtClose(FileHandle);

      if(VolumeHandle)
         NtClose(VolumeHandle);

      if(RetrievalPointers)
         RtlFreeMemory(RetrievalPointers);

      DbgPrint((
            ">> GetFilePhysicalOffset - %.8X\n",
            GetExceptionCode()));

      return GetExceptionCode();
    }

    return NtStatus;
}

mrkrcl 发表于 2012-2-3 13:36:17

ps: 请不要直接复制该代码在你的工程中,如果你的工程没有相关结构体的声明和函数的定义(该段代码中涉及的)是无法编译通过的` {:soso_e112:}

Tesla.Angela 发表于 2012-2-3 14:22:41

LZ是你原创的吗?如果是的话,请补齐结构体,并给出调用例子,我给你加精华确认,并加100水晶币。
如果不是原创的话,也请补齐结构体,并给出调用例子,并加100水晶币。
如果实在不能给出,那就算了。

xmlpull 发表于 2012-2-3 20:24:58

{:soso_e144:}Boss V 5!

abcgoodwei 发表于 2012-3-17 21:25:32

感谢分享

qwert502 发表于 2012-3-17 21:45:45

感谢分享

WG102514 发表于 2012-4-19 16:39:08

飘过

ggchen 发表于 2012-4-19 19:47:10

谢谢分享
页: [1]
查看完整版本: 某段直接从磁盘读取文件的源码