Lua os.remove() folder results in 'Permission denied' - windows

I am trying to use os.remove() to delete an empty folder in Windows using Lua but it just results in 'Permission Denied'. I can delete files with no problem.
However if I use os.execute() to call rmdir the folder does get deleted.
What are the limitations with os.remove() in a Windows environment?

The os.remove documentation states:
Deletes the file (or empty directory, on POSIX systems) with the
given name. If this function fails, it returns nil, plus a
string describing the error and the error code.
Windows is not POSIX compliant OS, therefore; exhibiting such a behaviour.
To get POSIX compatibility in Windows 7, you have to activate the Subsystem for UNIX-based applications (SUA / Interix) in Windows.

Related

How to prevent use of 8.3 names in HKCR open commands?

I tried to modify the open default command for .bat and .cmd files on Windows in order to open the Windows terminal instead of the legacy cmd.exe.
My modification to the user registry was:
(I had to use TotalReg from Pavel Yosifovitch to change the default value to REG_EXPAND_SZ).
The same default value was used for the batfile class.
The above definitions work almost properly.
There is a little issue though: when I now run a .bat or a .cmd file, the command line for wt.exe uses “legacy DOS 8.3 paths”, as well as the current working directory.
If my definition for the open command simply uses wt.exe instead of "%localappdata%\Microsoft\WindowsApps\wt.exe", then the problem disappears.
Is there a way to use the absolute path and still get the non-8.3 behavior?
When using %1, the shell tries to guess if the target supports long filenames. If you use %L, the shell always uses the long filename if the target is 32 or 64-bit. 16-bit applications presumably still get the short name?
%L is not officially documented anywhere but a Microsoft employee listed them in a comment here...

creating files with reserved names

Windows doesn't allow you to give files reserved names, such as con. However, WSL doesn't place any such restriction.
Creating a file called con produces an error: 'The specified device name is invalid.' Creating one with
touch con
in WSL does not produce any error, but then deleting it from Windows Explorer produces an error: 'Invalid file handle.' However,
rm con
in WSL deletes it without issue.
What is going on here? Why does WSL create a file with a reserved name without errors?
Windows blocks these file names from using them completely.(if e.g. you accessed a directory C:\CON\CON in an old windows version, you got a bluescreen)
So, you cannot access/create/delete them with cmd or explorer(It does not matter in which drive).
Howewer, the Filesystem does not block it. Because of this linux(maybe because something runs in the Windows Kernel?) shell emulators like git bash or wsl (I did not test cygwin) can create/access/delete these files even in the bootable Windows Partition.

Windows 7 registry %ProgramFiles% issue

I have some kind of windows appilcation, running on Windows 7 32-bit. I'm trying to register particular file extension open command with my application using windows registry. Such file extension is my own and also registered by me. The application installed in particular subdirectory within Program Files. I want my installer to register application properly for both 32 and 64-bit platfroms, since actual Program Files directory names can be different on x86 and x64 platfroms, while I need to specify path to my application, I'm using registry redirection %ProgramFiles%. Here I reproduce what records I make to registry:
// file extension
HKEY_CURRENT_USER
Software
Classes
.myext
Default REG_SZ myapp.myext
// application
HKEY_CURRENT_USER
Software
Classes
.myapp.myext
Shell
Open
Command
Default REG_SZ "%ProgramFiles%\path\to\my\app\myapp.exe" -u -i "%1"
Actual path to program files dir in my test machine is C:\Program Files
With such registration I receive an error:
Windows cannot access the specified device path, or file. You may not
have the appropriate permissions to access the item.
If I replace %ProgramFiles% with actual C:\Program Files everything works fine. Also when I'm using same path: "%ProgramFiles%\path\to\my\app\myapp.exe" to run application from console everything works fine too. What can be reason of such issue.
%ProgramFiles% evaluates to the 32 bit program files dir in a 32 bit process and the 64 bit program files dir in a 64 bit process. However, the location of your executable does not depend on the bitness of the shell, which is the thing that reads those registry settings. You want to write the following value to the registry:
"C:\Program Files (x86)\path\to\my\app\myapp.exe" -u -i "%1"
where I assume that is the path to the 32 bit program files dir. You should not be writing an environment variable into this registry key. Your install program will already know the full path to the executable, and you should simply write that.
One issue that I think may be confusing you is that you may be under the believe that the program files directories are subject to file system redirection. They are not.
As an aside, if you ever need to write an environment variable into the registry, and want it to be expanded upon reading, use REG_EXPAND_SZ rather than REG_SZ.

Is it possible to properly execute qwinsta from a Cygwin ssh session?

I have Cygwin running on a Windows 7 machine and have the Cygwin ssh server running on it. On Linux I have a shell script where I want to do
ssh myuser#mymachine "qwinsta | grep Active"
to see who is logged in. This worked fine for a Windows Server 2008 R2 machine, but seems to have problems on Windows 7.
If I try this on the Windows 7 machine, I get:
bash: qwinsta: command not found
Now, here is where the weirdness begins...
If I login to the Windows 7 machine normally and look in C:\Windows\System32 with Windows Explorer, I see qwinsta.exe. If I open a CMD session and do a dir in C:\Windows\System32, I see qwinsta.exe. If I open a Cygwin shell and do a ls qwinsta.exe in /cygdrive/c/Windows/System32, I get:
ls: cannot access qwinsta.exe: No such file or directory
If I do a cmd /c dir C:\\\\Windows\\\\System32\\\\qwinsta.exe from the Cygwin shell, I get a "File Not Found"
If I copy qwinsta.exe into my Cygwin home directory, then it is visible in my home directory with ls. If I try to run this local copy of qwinsta from the Cygwin shell, it runs, but it also outputs a line:
{Message(): LoadString failed, Error 15105, (0x00003B01)}
What's up with qwinsta on Windows 7?
The problem is that qwinsta.exe is not actually located in C:\Windows\System32. It is actually found in
C:\Windows\winsxs\amd64_microsoft-windows-t..commandlinetoolsmqq_31bf3856ad364e35_6.XX.XXX.XXXX_none_XXXXXXXX\qwinsta.exe
Using the above path (or a softlink to the same) will run qwinsta.exe as it exists on any machine, and will not require you to copy the executable to your home directory.
The error message {Message(): LoadString failed, Error 15105, (0x00003B01)} is about the Multilinugal User Interface (localization) system not being able to find error message localization information for the program being run (see System Error Codes). In this case, it appears that the cygwin shell does not provide qwinsta.exe with the information it needs to find qwinsta.exe.mui in your language's locale folder (usually C:\Windows\System32\en-US or whatever your locale happens to be). Looking into this folder is somewhat misleading, as explorer will show the file in this directory, but when you run ls /cygdrive/c/Windows/System32/en-US, there is no qwinsta.exe.mui file. I suspect this has something to do with the new linking structure in NTFS (see mklink command), but I haven't figured out how to fix this part of the problem yet.
Solved:
First, go to C:\Windows\winsxs\amd64_microsoft-windows-t..commandlinetoolsmqq_31bf3856ad364e35_6.1.7600.16385_none_851e6308c5b62529
(Copy and pasting that location works just as well as manually finding it.)
You should find three files: Msg.exe , Quser.exe, and qwinsta.exe .
Copy these files to your C:\Windows\system32 folder
Next, go to C:\Windows\winsxs\amd64_microsoft-windows-t..etoolsmqq.resources_31bf3856ad364e35_6.1.7600.16385_en-us_7bef78d9f4a6a8ac
You should find three similarly named files, except these will end with .mui.
Copy all three of these files to your C:\Windows\system32\en-US folder.
Now try running the msg program. It should work without issue.
Windows 10
Following on from Erutan2099's answer, for Windows 10 it's a little trickier, since the files are compressed (binary delta compression, file signature 44 43 53 01). Trying to use them as is throws an Unsupported 16-Bit Application error:
The program or feature "\??\C:\Windows\System32\msg.exe" cannot start or run due to incompatibility with 64-bit versions of Windows. Please contact the software vendor to ask if a 64-bit Windows compatible version is available.
A specific tool has been made to decompress such files: SXSEXP (this post pointed me in the right direction)
Usage:
> sxsexp64.exe msg.exe expand\msg.exe
Processing target path msg.exe
msg.exe => expand\msg.exe
File size 12602 bytes
DCS_HEADER found.
NumberOfBlocks 1
UncompressedFileSize 26112
DCS_BLOCK #1
Block->CompressedBlockSize 0000312A
Block->DecompressedBlockSize 00006600
Operation Successful
> sxsexp64.exe msg.exe.mui expand\msg.exe.mui
Processing target path msg.exe.mui
msg.exe.mui => expand\msg.exe.mui
File size 2150 bytes
DCS_HEADER found.
NumberOfBlocks 1
UncompressedFileSize 7680
DCS_BLOCK #1
Block->CompressedBlockSize 00000856
Block->DecompressedBlockSize 00001E00
Operation Successful
These decompressed files can now be copied to C:\Windows\System32 and C:\Windows\System32\en-US respectively.
Example:
> msg * Hello, World!

Cygwin GCC + WinXP cmd.exe does nothing

My basic problem is that if I run GCC from the windows command line (cmd.exe in Windows XP) and it does nothing: no .o files are created, no error messages, nothing. It will only throw an error message if I use DOS-style paths, but nothing else. When I run from the Cygwin shell then it will throws error messages as appropriate for the errors in the source and produces the .o files as it needs. Using 'make' from the DOS command line doesn't work either. Has anyone encountered this behavior before?
I've actually made some progress on this. Background:
I have WinAVR installed and its bin directories set in my PATH. WinAVR is GCC and associated development utilities but for the AVR 8-bit microcontroller. It shares many utility names with regular GCC.
In the past I remember Cygwin putting its bin directories in the PATH. It didn't seem to do this this time, so I put 'C:\cygwin\bin' into the PATH and then later 'C:\cygwin\usr\bin' there as well.
The latest release of Cygwin has issues with the way it handles files. Basically, gcc.exe is not an executable, but a type of symlink to the actual executable (which is either gcc-3.exe or gcc-4.exe depending on what you have installed). In the BASH shell these symlinks are easily resolved, in cmd.exe they are not. This means that if you attempt to enter 'gcc' into cmd.exe as a command it will respond 'Access is denied'. The solution for that is to call the actual GCC file name (gcc-4) instead of the symlink.
The solution seems to have come by rearranging my PATH. To edit the PATH environment variable, right click on 'My Computer' and go to properties, then Advanced and then Environment Variables. Under 'System Variables' find 'Path' and double click it to edit. Remove all entries that have C:\cygwin in them and then go to the FRONT of the PATH and enter them there. For me it was C:\cygwin\bin and C:\cygwin\usr\bin. The important part for me was making sure that the Cygwin entries were before the WinAVR entries. I noticed that when I tried to call 'make' in cmd.exe it was calling the WinAVR version instead of the Cygwin version. This lead me to rearrange my path and after some fooling around it became clear that using gcc-4 from the cmd.exe shell was working. It then worked in Code::Blocks as well and I was off.
Alternatively, it might have just fixed itself from something else entirely. Computers have a way of doing that.
Alternatively you can delete file: gcc.exe which is a file link and rename
the actual gcc executable file: gcc-3.exe (or gcc-4.exe depends on your version) to gcc.exe

Resources