win_file: Handle [] in paths, fix touch in check mode (#37901)

* win_file: Handle [] in paths, fix touch in check mode

* Fixed typo for p/invoke command
This commit is contained in:
Jordan Borean 2018-04-27 07:57:16 +10:00 committed by GitHub
commit 4b57fa91d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 32 deletions

View file

@ -28,12 +28,19 @@ using System.Runtime.InteropServices;
namespace Ansible.Command {
public class SymLinkHelper {
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool RemoveDirectory(string lpPathName);
public static extern bool DeleteFileW(string lpFileName);
public static void DeleteSymLink(string linkPathName) {
bool result = RemoveDirectory(linkPathName);
if (result == false)
throw new Exception(String.Format("Error deleting symlink: {0}", new Win32Exception(Marshal.GetLastWin32Error()).Message));
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool RemoveDirectoryW(string lpPathName);
public static void DeleteDirectory(string path) {
if (!RemoveDirectoryW(path))
throw new Exception(String.Format("RemoveDirectoryW({0}) failed: {1}", path, new Win32Exception(Marshal.GetLastWin32Error()).Message));
}
public static void DeleteFile(string path) {
if (!DeleteFileW(path))
throw new Exception(String.Format("DeleteFileW({0}) failed: {1}", path, new Win32Exception(Marshal.GetLastWin32Error()).Message));
}
}
}
@ -46,13 +53,19 @@ function Remove-File($file, $checkmode) {
if ($file.Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
# Bug with powershell, if you try and delete a symbolic link that is pointing
# to an invalid path it will fail, using Win32 API to do this instead
if (-Not $checkmode) {
[Ansible.Command.SymLinkHelper]::DeleteSymLink($file.FullName)
if ($file.PSIsContainer) {
if (-not $checkmode) {
[Ansible.Command.SymLinkHelper]::DeleteDirectory($file.FullName)
}
} else {
if (-not $checkmode) {
[Ansible.Command.SymlinkHelper]::DeleteFile($file.FullName)
}
}
} elseif ($file.PSIsContainer) {
Remove-Directory -directory $file -checkmode $checkmode
} else {
Remove-Item -Path $file.FullName -Force -WhatIf:$checkmode
Remove-Item -LiteralPath $file.FullName -Force -WhatIf:$checkmode
}
} catch [Exception] {
Fail-Json $result "Failed to delete $($file.FullName): $($_.Exception.Message)"
@ -63,21 +76,24 @@ function Remove-Directory($directory, $checkmode) {
foreach ($file in Get-ChildItem $directory.FullName) {
Remove-File -file $file -checkmode $checkmode
}
Remove-Item -Path $directory.FullName -Force -Recurse -WhatIf:$checkmode
Remove-Item -LiteralPath $directory.FullName -Force -Recurse -WhatIf:$checkmode
}
if ($state -eq "touch") {
if (Test-Path -Path $path) {
(Get-ChildItem -Path $path).LastWriteTime = Get-Date
if (Test-Path -LiteralPath $path) {
if (-not $check_mode) {
(Get-ChildItem -LiteralPath $path).LastWriteTime = Get-Date
}
$result.changed = $true
} else {
Write-Output $null | Out-File -FilePath $path -Encoding ASCII -WhatIf:$check_mode
Write-Output $null | Out-File -LiteralPath $path -Encoding ASCII -WhatIf:$check_mode
$result.changed = $true
}
}
if (Test-Path -Path $path) {
$fileinfo = Get-Item -Path $path
if (Test-Path -LiteralPath $path) {
$fileinfo = Get-Item -LiteralPath $path
if ($state -eq "absent") {
Remove-File -file $fileinfo -checkmode $check_mode
$result.changed = $true
@ -109,7 +125,7 @@ if (Test-Path -Path $path) {
New-Item -Path $path -ItemType Directory -WhatIf:$check_mode | Out-Null
} catch {
if ($_.CategoryInfo.Category -eq "ResourceExists") {
$fileinfo = Get-Item $_.CategoryInfo.TargetName
$fileinfo = Get-Item -LiteralPath $_.CategoryInfo.TargetName
if ($state -eq "directory" -and -not $fileinfo.PsIsContainer) {
Fail-Json $result "path $path is not a directory"
}