Powershell: "Incorrect function" exception when running an exe not in C:\

Created on 9 Sep 2020  ·  11Comments  ·  Source: PowerShell/PowerShell

Steps to reproduce

C:\Users\mbj>C:\scoop\apps\powershell-preview\7.1.0-preview.7\pwsh.exe
PowerShell 7.1.0-preview.7
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

OperationStopped: C:\Users\mbj\Documents\PowerShell\Microsoft.PowerShell_profile.ps1:19
Line |
  19 |  cat $PROFILE_ORIG | H:\usr\bin\ssed.exe -n ("aliases","filters","path …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Incorrect function.

Loading personal and system profiles took 2426ms.
PS C:\Users\mbj>
1> h:\usr\bin\ssed.exe -n 19p $PROFILE
OperationStopped: Incorrect function.
PS C:\Users\mbj>
2>

Expected behavior

C:\Users\mbj>C:\scoop\apps\powershell-preview\7.1.0-preview.6\pwsh.exe
PowerShell 7.1.0-preview.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

   A new PowerShell preview release is available: v7.1.0-preview.7
   Upgrade now, or check out the release page at:
     https://aka.ms/PowerShell-Release?tag=v7.1.0-preview.7

Loading personal and system profiles took 1354ms.
PS C:\Users\mbj>
1> h:\usr\bin\ssed.exe -n 19p $PROFILE
cat $PROFILE_ORIG | H:\usr\bin\ssed.exe -n ("aliases","filters","path" |ForEach-Object{ "-e /^#region $_/,/^#endregion/p" }) | out-string | invoke-expression

Suggestion [4,General]: The most similar commands are: cmpcfg, tcfg, sacfg, pbcfg, rtcfg, gcfg, upcfg, copy, clc, cnsn.
PS C:\Users\mbj>
2>
C:\Users\mbj>
C:\Users\mbj>
C:\Users\mbj>C:\scoop\apps\powershell-preview\7.1.0-preview.5\pwsh.exe
PowerShell 7.1.0-preview.5
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

   A new PowerShell preview release is available: v7.1.0-preview.7
   Upgrade now, or check out the release page at:
     https://aka.ms/PowerShell-Release?tag=v7.1.0-preview.7

Loading personal and system profiles took 1360ms.
PS C:\Users\mbj>
1> h:\usr\bin\ssed.exe -n 19p $PROFILE
cat $PROFILE_ORIG | H:\usr\bin\ssed.exe -n ("aliases","filters","path" |ForEach-Object{ "-e /^#region $_/,/^#endregion/p" }) | out-string | invoke-expression

Suggestion [4,General]: The most similar commands are: cmpcfg, upcfg, sacfg, rtcfg, pbcfg, gcfg, tcfg, copy, clc, cnsn.
PS C:\Users\mbj>
2>
C:\Users\mbj>
C:\Users\mbj>
C:\Users\mbj>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

commandline 2020-09-09T13:25:39.1303419Z C:\Users\mbj
$ h:\usr\bin\ssed.exe -n 19p $PROFILE
    Write-Host (get-location) -ForegroundColor Magenta
commandline 2020-09-09T13:25:46.5978391Z C:\Users\mbj
$

Actual behavior

Exception             : System.ComponentModel.Win32Exception (1): Incorrect function.
                           at Microsoft.PowerShell.Commands.InternalSymbolicLinkLinkCodeMethods.WinInternalGetTarget(SafeFileHandle handle)
                           at Microsoft.PowerShell.Commands.InternalSymbolicLinkLinkCodeMethods.WinInternalGetTarget(String path)
                           at System.Management.Automation.NativeCommandProcessor.CheckIfWindowsApplication(String fileName)
                           at System.Management.Automation.NativeCommandProcessor.get_IsWindowsApplication()
                           at System.Management.Automation.NativeCommandProcessor.CalculateIORedirection(Boolean& redirectOutput, Boolean& redirectError, Boolean& redirectInput)
                           at System.Management.Automation.NativeCommandProcessor.InitNativeProcess()
                           at System.Management.Automation.NativeCommandProcessor.Prepare(IDictionary psDefaultParameterValues)
                           at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
                           at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
                           at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
                           at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[]
                        pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
                           at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
                           at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          :
CategoryInfo          : OperationStopped: (:) [], Win32Exception
FullyQualifiedErrorId : System.ComponentModel.Win32Exception
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, C:\Users\mbj\Documents\PowerShell\Microsoft.PowerShell_profile.ps1: line 19
                        at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
PSMessageDetails      :

Environment data

PS C:\Users\mbj>
5> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.0-preview.7
PSEdition                      Core
GitCommitId                    7.1.0-preview.7
OS                             Microsoft Windows 10.0.20206
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Bug WG-Engine-Providers

Most helpful comment

I'm 95% certain that exfat has no support for reparse points which explains why DeviceIoControl is returning ERROR_INVALID_FUNCTION for objects on that file system. The PowerShell code would have to be modified to handle such a situation. GetVolumeInformationByHandleW can be used to detect if the volume supports reparse points but honestly it seems like just ignoring ERROR_INVALID_FUNCTION is easier.

All 11 comments

PS C:\Users\mbj>
1> H:\usr\bin\ssed.exe -n 19p $PROFILE
OperationStopped: Incorrect function.
PS C:\Users\mbj>
2> cd  H:\usr\bin\
PS H:\usr\bin>
3> .\ssed.exe -n 19p $PROFILE
OperationStopped: Incorrect function.
PS H:\usr\bin>
4> cp .\ssed.exe ~
PS H:\usr\bin>
5> C:\Users\mbj\ssed.exe -n 19p $PROFILE
cat $PROFILE_ORIG | H:\usr\bin\ssed.exe -n ("aliases","filters","path" |ForEach-Object{ "-e /^#region $_/,/^#endregion/p" }) | out-string | invoke-expression
PS H:\usr\bin>
6>

@blancmangit is H:\ a local drive or a network share?

Local

What is a file system on the H: drive? And What is ssed.exe file type? Hardlink, symlink?

The failure here is occurring when PowerShell checks to see if ssed.exe is a reparse point and to get the target to execute of that reparse point. The error is being raised in WinInternalGetTarget and based on the message that is returned I would bet that it's the call to DeviceIOControl that is returning the exception.

The underlying Win32 error is ERROR_INVALID_FUNCTION which has the message matching the error PowerShell reports back

Incorrect function.

The docs for FSCTL_GET_REPARSE_POINT indicate the types of filesystems that support this FSCTL code but I would also guess that H: is an FAT32 formatted drive (or something that is not NTFS/ReFS). The fact that the path of ssed is in H:\usr\bin\ makes it sound like it's a WSL path. Knowing if you are using WSL 1 or WSL 2 would be helpful, or even what is backing the H drive and how it is formatted.

It sounds like we need to have a further check on WinInternalGetTarget to only call DeviceIoControl if the Reparse Point attribute is there or just add ERROR_INVALID_FUNCTION to the list of error codes to ignore for this call.

The drive may certainly be exFAT. I won’t be able to check that for suretill Monday at the earliest.

The file is a plain exe, not any kind of hard or symbolic link and it is not related to WSL. In fact the same exception is raised for any exe I’ve tried on that drive.

I'm 95% certain that exfat has no support for reparse points which explains why DeviceIoControl is returning ERROR_INVALID_FUNCTION for objects on that file system. The PowerShell code would have to be modified to handle such a situation. GetVolumeInformationByHandleW can be used to detect if the volume supports reparse points but honestly it seems like just ignoring ERROR_INVALID_FUNCTION is easier.

No need does P/Invoke to check if reparse points are supported. We should return null if ERROR_INVALID_FUNCTION - the error code in the context implicitly says that reparse points are not supported..

i have same problem on preview7,i allready return to preview6,problem gone.

PS C:\ProgramData\kasini3000> D:\aliyun_go\aliyun-3。0。31.exe
OperationStopped: 函数不正确。
PS C:\ProgramData\kasini3000> D:\aliyun_go\aliyun-3。0。58.exe
OperationStopped: 函数不正确。
PS C:\ProgramData\kasini3000> aria2c --help
OperationStopped: 函数不正确。

You can download artifact from #13634 and check.

You can download artifact from #13634 and check.

I confirm this fixes the problem for me in a Virtualbox shared directory in a Windows 10 guest!

It was a bit of a struggle to discover the artifacts, so writing notes for others:

  1. Clicked the Details in the "PowerShell-CI-windows (Packaging for Windows Windows Packaging)" message in the PR
  2. Clicked the "0 errors / 0 warnings" link
  3. Hovered over "build" and clicked the meatball menu in its right side and selected Download artifacts
  4. Extracted the contents of public/ into my local Powershell directory, overwriting existing files
Was this page helpful?
0 / 5 - 0 ratings

Related issues

andschwa picture andschwa  ·  3Comments

rudolfvesely picture rudolfvesely  ·  3Comments

ajensenwaud picture ajensenwaud  ·  3Comments

rkeithhill picture rkeithhill  ·  3Comments

JohnLBevan picture JohnLBevan  ·  3Comments