Repository: denoland/deno
File: ext/fs/std_fs.rs (Rust)

Code before:
    handle: winapi::shared::ntdef::HANDLE,
  ) -> Result<FILE_ALL_INFORMATION, NTSTATUS> {
    use windows_sys::Win32::Foundation::RtlNtStatusToDosError;
    use windows_sys::Win32::Foundation::ERROR_MORE_DATA;
    use windows_sys::Win32::System::IO::IO_STATUS_BLOCK;
    use windows_sys::Wdk::Storage::FileSystem::NtQueryInformationFile;

    let mut info = std::mem::MaybeUninit::<FILE_ALL_INFORMATION>::zeroed();
    let mut io_status_block = std::mem::MaybeUninit::<IO_STATUS_BLOCK>::zeroed();
    let status = NtQueryInformationFile(
      handle as _,
      io_status_block.as_mut_ptr(),
      info.as_mut_ptr() as *mut _,
      std::mem::size_of::<FILE_ALL_INFORMATION>() as _,
      18, /* FileAllInformation */
    );

    if status < 0 {
      let converted_status = RtlNtStatusToDosError(status);

      // If error more data is returned, then it means that the buffer is too small to get full filename information
      // to have that we should retry. However, since we only use BasicInformation and StandardInformation, it is fine to ignore it
      // since struct is populated with other data anyway.
      /// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryinformationfile#remarks

      if converted_status != ERROR_MORE_DATA {
        return Err(converted_status as NTSTATUS);
      }
    }

    Ok(info.assume_init())
  }

  // SAFETY: winapi calls
  unsafe {
    let mut path: Vec<_> = path.as_os_str().encode_wide().collect();
    path.push(0);
    let file_handle = CreateFileW(
      path.as_ptr(),
      0,
      FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
      std::ptr::null_mut(),
      OPEN_EXISTING,
      file_flags,
      std::ptr::null_mut(),
    );
    if file_handle == INVALID_HANDLE_VALUE {
      return Err(std::io::Error::last_os_error().into());
    }

    let result = get_dev(file_handle);

Review comment (bug):
According to Microsoft docs (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryinformationfile#remarks) it is fine to ignore it as long as we don't care about full file name "If NtQueryInformationFile fails because of a buffer overflow, drivers that implement FileNameInformation should return as many WCHAR characters of the file name as will fit in the buffer and specify the full length that is required in the FileNameLength parameter of the [FILE_NAME_INFORMATION](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_name_information) structure.". To make it work without an error, we would have to query the sys call again with size buffer of struct + length of the file name, as the FILE_ALL_INFORMATION has variable size in FILE_NAME_INFORMATION struct (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_name_information)

Code after:
    handle: winapi::shared::ntdef::HANDLE,
  ) -> Result<FILE_ALL_INFORMATION, NTSTATUS> {
    use windows_sys::Wdk::Storage::FileSystem::NtQueryInformationFile;
    use windows_sys::Win32::Foundation::RtlNtStatusToDosError;
    use windows_sys::Win32::Foundation::ERROR_MORE_DATA;
    use windows_sys::Win32::System::IO::IO_STATUS_BLOCK;

    let mut info = std::mem::MaybeUninit::<FILE_ALL_INFORMATION>::zeroed();
    let mut io_status_block =
      std::mem::MaybeUninit::<IO_STATUS_BLOCK>::zeroed();
    let status = NtQueryInformationFile(
      handle as _,
      io_status_block.as_mut_ptr(),
      info.as_mut_ptr() as *mut _,
      std::mem::size_of::<FILE_ALL_INFORMATION>() as _,
      18, /* FileAllInformation */
    );

    if status < 0 {
      let converted_status = RtlNtStatusToDosError(status);

      // If error more data is returned, then it means that the buffer is too small to get full filename information
      // to have that we should retry. However, since we only use BasicInformation and StandardInformation, it is fine to ignore it
      // since struct is populated with other data anyway.
      // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryinformationfile#remarksdd
      if converted_status != ERROR_MORE_DATA {
        return Err(converted_status as NTSTATUS);
      }
    }

    Ok(info.assume_init())
  }

  // SAFETY: winapi calls
  unsafe {
    let mut path: Vec<_> = path.as_os_str().encode_wide().collect();
    path.push(0);
    let file_handle = CreateFileW(
      path.as_ptr(),
      0,
      FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
      std::ptr::null_mut(),
      OPEN_EXISTING,
      file_flags,
      std::ptr::null_mut(),
    );
    if file_handle == INVALID_HANDLE_VALUE {
      return Err(std::io::Error::last_os_error().into());
    }

    let result = get_dev(file_handle);