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); }