示例#1
0
 public bool Handle(WindowsKey key)
 {
     if (!KeyIdentity.IsPredefined(key.Handle))
     {
         return Win32Exception.CheckIfFoundAndNoError(
             Win32Api.NtQueryKey(key.Handle, KeyInformationClass_, KeyInformation_, Length_,
             out ResultLength_));
     }
     // Predefined key handle values are valid only on the advapi32.dll level
     // on the ntdll.dll level we have to replace them with appropriate ntdll.dll handles
     IntPtr hNtKey = IntPtr.Zero;
     string objectName = KeyIdentity.GetSystemBasePath(key.Handle);
     Win32Api.UNICODE_STRING usObjectName = new Win32Api.UNICODE_STRING();
     usObjectName.Length = unchecked((ushort)(sizeof(char) * objectName.Length));
     usObjectName.MaximumLength = usObjectName.Length;
     using (HGlobalPtr pObjectNameBuffer = new HGlobalPtr(Marshal.StringToHGlobalUni(objectName)))
     {
         usObjectName.Buffer = pObjectNameBuffer.Ptr;
         using (HGlobalPtr pObjectName = new HGlobalPtr(Marshal.SizeOf(typeof(Win32Api.UNICODE_STRING))))
         {
             Marshal.StructureToPtr(usObjectName, pObjectName.Ptr, false);
             Win32Api.OBJECT_ATTRIBUTES oa = new Win32Api.OBJECT_ATTRIBUTES();
             oa.Length = unchecked((uint)Marshal.SizeOf(typeof(Win32Api.OBJECT_ATTRIBUTES)));
             oa.RootDirectory = IntPtr.Zero;
             oa.ObjectName = pObjectName.Ptr;
             oa.Attributes = (uint)Win32Api.ObjectAttributes.OBJ_CASE_INSENSITIVE;
             oa.SecurityDescriptor = IntPtr.Zero;
             oa.SecurityQualityOfService = IntPtr.Zero;
             using (HGlobalPtr pOA = new HGlobalPtr(Marshal.SizeOf(typeof(Win32Api.OBJECT_ATTRIBUTES))))
             {
                 Marshal.StructureToPtr(oa, pOA.Ptr, false);
                 if (!Win32Exception.CheckIfFoundAndNoError(
                     Win32Api.NtOpenKey(out hNtKey, (uint)Win32Api.KeySecurity.KEY_QUERY_VALUE, pOA.Ptr)))
                 {
                     return false;
                 }
                 try
                 {
                     return Win32Exception.CheckIfFoundAndNoError(
                         Win32Api.NtQueryKey(hNtKey, KeyInformationClass_, KeyInformation_, Length_,
                         out ResultLength_));
                 }
                 finally
                 {
                     Win32Api.NtClose(hNtKey);
                 }
             }
         }
     }
 }
        /// <summary>Given a file reference number GetPathFromFrn() calculates the full path in the out parameter 'path'.</summary>
        /// <param name="frn">A 64-bit file reference number</param>
        /// <param name="path"></param>
        /// <returns>
        /// USN_JOURNAL_SUCCESS                 GetPathFromFrn() function succeeded.
        /// VOLUME_NOT_NTFS                     volume is not an NTFS volume.
        /// INVALID_HANDLE_VALUE                NtfsUsnJournal object failed initialization.
        /// ERROR_ACCESS_DENIED                 accessing the USN journal requires admin rights, see remarks.
        /// INVALID_FILE_REFERENCE_NUMBER       file reference number not found in Master File Table.
        /// ERROR_INVALID_FUNCTION              error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_FILE_NOT_FOUND                error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_PATH_NOT_FOUND                error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_TOO_MANY_OPEN_FILES           error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_INVALID_HANDLE                error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_INVALID_DATA                  error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_NOT_SUPPORTED                 error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_INVALID_PARAMETER             error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// ERROR_INVALID_USER_BUFFER           error generated by NtCreateFile() or NtQueryInformationFile() call.
        /// USN_JOURNAL_ERROR                   unspecified USN journal error.
        /// </returns>
        /// <remarks>
        /// If function returns ERROR_ACCESS_DENIED you need to run application as an Administrator.
        /// </remarks>
        public int GetPathFromFileReference(ulong frn, out string path)
        {
            path = null;
            var lastError = (int)UsnJournalReturnCode.VOLUME_NOT_NTFS;

            var sw = new Stopwatch();

            sw.Start();

            if (bNtfsVolume)
            {
                if (_usnJournalRootHandle.ToInt64() != Win32Api.INVALID_HANDLE_VALUE)
                {
                    if (frn != 0)
                    {
                        lastError = (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS;

                        long allocSize = 0;
                        Win32Api.UNICODE_STRING unicodeString;
                        var objAttributes = new Win32Api.OBJECT_ATTRIBUTES();
                        var ioStatusBlock = new Win32Api.IO_STATUS_BLOCK();
                        var hFile         = IntPtr.Zero;

                        var buffer       = Marshal.AllocHGlobal(4096);
                        var refPtr       = Marshal.AllocHGlobal(8);
                        var objAttIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(objAttributes));

                        // Pointer >> fileid.
                        Marshal.WriteInt64(refPtr, (long)frn);

                        unicodeString.Length        = 8;
                        unicodeString.MaximumLength = 8;
                        unicodeString.Buffer        = refPtr;

                        // Copy unicode structure to pointer.
                        Marshal.StructureToPtr(unicodeString, objAttIntPtr, true);


                        //  InitializeObjectAttributes.
                        objAttributes.Length        = (ulong)Marshal.SizeOf(objAttributes);
                        objAttributes.ObjectName    = objAttIntPtr;
                        objAttributes.RootDirectory = _usnJournalRootHandle;
                        objAttributes.Attributes    = (int)Win32Api.OBJ_CASE_INSENSITIVE;


                        var fOk = Win32Api.NtCreateFile(ref hFile, FileAccess.Read, ref objAttributes, ref ioStatusBlock, ref allocSize, 0,
                                                        FileShare.ReadWrite, Win32Api.FILE_OPEN, Win32Api.FILE_OPEN_BY_FILE_ID | Win32Api.FILE_OPEN_FOR_BACKUP_INTENT, IntPtr.Zero, 0);


                        if (fOk == 0)
                        {
                            fOk = Win32Api.NtQueryInformationFile(hFile, ref ioStatusBlock, buffer, 4096, Win32Api.FILE_INFORMATION_CLASS.FileNameInformation);

                            if (fOk == 0)
                            {
                                // The first 4 bytes are the name length.
                                var nameLength = Marshal.ReadInt32(buffer, 0);

                                // The next bytes are the name.
                                path = Marshal.PtrToStringUni(new IntPtr(buffer.ToInt64() + 4), nameLength / 2);
                            }
                        }

                        Win32Api.CloseHandle(hFile);
                        Marshal.FreeHGlobal(buffer);
                        Marshal.FreeHGlobal(objAttIntPtr);
                        Marshal.FreeHGlobal(refPtr);
                    }
                }
            }

            ElapsedTime = TimeSpan.FromMilliseconds(sw.ElapsedMilliseconds);

            return(lastError);
        }