How to find & close all open file handles on a removable drive (before ejecting) - visual-c++

I'm trying to eject a (virtual) removable drive, and it fails because there are some file handles open, maybe explorer windows. What's the best way to get all the open handles to files on that drive and close them?
Is it also feasible (within user-mode) to find any processes running off that drive, so I can warn the user with the process name?
Ideally I'd like to do this within a user-mode app rather than require admin privileges.
I'm using VC++ in Visual Studio 2005, in an MFC app, but samples in any language would be welcome!

The Process Explorer utility can search for open handles, but I don't know whether it can do so without elevated privileges. From what I've been able to gather, it does this using the "Performance Counters" API.
I think this article does what you need, enumerate the running processes, enumerate the handles for each one, look for a file handle referencing a path on the drive in question:
How to enumerate process' handles?

Related

It is possible to track what apps are in use and what file is opened with nodejs

For a future project, I need to track user activity to record their productivity time. I want to detect which file is currently open in apps like Adobe Photoshop for example and detect when the user switches to other app or another file/tab.
To make my desktop app, I wish to use electron JS
Can you just give me some tracks to follow ?I don't find any nodejs library that allow me to do that, but I know that is possible because it already done with electron apps like:
Chronos https://electronjs.org/apps/chronos-timetracker
Paymo https://electronjs.org/apps/paymo-time-tracker
ScreenAware https://electronjs.org/apps/screenaware
And an other App which not seems to be built with electron :
https://desktime.com/features
Thanks for your help
node.js doesn't have the capabilities you require, however it can call external programs to get the job done. The way I see it, you would need to have a PowerShell script (or C# program) to get the active window from the operating system, and find all open file handles for the process behind that window. You would invoke this script from node, and build your gui around it.
A good starting point is this module active-window which works exacty as I described: a nodejs process calls some external scripts (in bash/PowerShell) that use OS specific primitives to get the active window.
To get the list of files opened by a process, you could use the handle utility from Sysinternals. However you may run into a small problem: apps like Photoshop usually don't keep the file handle open, they just open it when saving the file. This means that you won't always be able to detect open files. I guess trial and error is your friend here.
To find open tabs, it's more complicated. Tabs usually indicate the internal state of an app, and this information is held in memory. Some apps might offer an API, but that's not guaranteed. I guess screenshots are the way to go here.

Using DirectXTK to save screenshots in Windows Store app (Metro)

I'm working on a C++ Windows Store DirectX app and I'm trying to save screenshots to disk every so often.
I am using the DirectX Tool Kit (DirectXTK) and the function SaveDDSTextureToFile which returns an HRESULT.
The problem is that the returned HRESULT is always:
E_ACCESSDENIED General access denied error.
I assume this is some permissions/capabilities thing (it being a windows store app) but I can't find what I need to ask for permission for to be able to save files to disk.
The DirectX ToolKit says it is for Windows store applications as well as desktop applications but I can't find any information on their codeplex either.
Does anyone know what I need to have permission to do for this to work?
Thanks for your time.
Windows Store apps are sandboxed and have fewer permissions than desktop apps, especially when it comes to file access. By default, apps only have access to write to the local storage directory, which isn't easily accessible from the shell. If you want to save to the Pictures or Documents library, you will need to specify this access in the package manifest. Additionally, you will need to use the WinRT file APIs to write the DDS files. To do this, use SaveDDSTextureToMemory, then write the resulting raw DDS data to the StorageFile. Check out the File access sample for more info on the WinRT APIs involved in writing this data as a file.
I've managed to find a way to do it. Basically as MooseBoys says you cannot save to anywhere because the app is sandboxed.
You can however save to the TempState folder of your apps package in AppData, which is all I need because I'm using this feature for debugging.
So the line I call is:
DirectX::SaveWICTextureToFile(deviceContext, texture2D, GUID_ContainerFormatPng, L"C:\\Users\\USERNAME\\AppData\\Local\\Packages\\PACKAGENAME\\TempState\\test.png");
And this works great.

How to use WMI to copy a file from computer A to computer B using unmanaged VC++

I need to have my unmanaged VC++ program able to copy a file from the computer the application is on to one of 100 other computers.
I have administrator access on each computer, so that won't be a problem.
It seems I need to use WMI to do this, but I am having a hard time getting it to work properly by looking at examples in: http://msdn.microsoft.com/en-us/library/windows/desktop/aa394558(v=vs.85).aspx
I am curious of the CopyFile family of functions should work:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363851(v=vs.85).aspx
This is a console application that doesn't use MFC and isn't using ATL.
Is there a good example of how to do what I am trying to do that will work on WinXP and Windows 7?
The easiest way is probably to start by creating a network connection with WNetAddConnection2, then copy the file with something like CopyFile or CopyFileEx. When you're done, it would be courteous to use WNetCancelConnection2 to remove the network connection.
The only WMI class designed to manipulate files is the CIM_DataFile class, they include a set of methods (Copy, CopyEx) to copy files but only works in the target machine, this means which you cannot copy a file from one machine to another using the WMI (at least which you use a network drive or shared).

Accessing C:\ drive on Windows 7

I have full admin privileges on my Windows 7 machine but when I run my application which creates a file on c:\ drive I get error code 5 (Access is denied). I know windows 7 doesn't allow creating files in protected areas like c drive and program files and file explorer brings up 'administrative' message box if I copy a file there from somewhere else after which it does allows but can my application obtain write level access?
In my application, user gets to pick the folder where they want to create the file so if they choose c:\ drive s/he will obviously get this error which is not desirable.
void CTestDlg::OnBnClickedButtonCreate()
{
CFile f;
CFileException e;
TCHAR* pszFileName = _T("c:\\test.txt"); // here i am hard coding path for simplicity.
if(!f.Open(pszFileName, CFile::modeCreate | CFile::modeWrite, &e))
{
TRACE(_T("File could not be opened %d\n"), e.m_cause);
}
}
As far as I have researched it seems I can't by-pass the UAC dialog which is fine but my application don't even present it (which is understandable as well) but what are my options?
I see my only option is to detect this in my own application if this is Windows 7 OS and than check for file path before creating the file and present a more user friendly message 'windows 7 doesn't like you to create file in this folder, choose a different folder or go back to xp'. Is this scheme the way to go on Windows 7? Is there any other way?
As Kolink noted, your application needs to run with administrator privileges. In order to do that automatically, embed a manifest as explained here.
EDIT: For VS2010: Project Properties > Configuration Properties > Linker > Manifest File Change the 'UAC Execution Level' to the desired value.
Either don't try to write to protected areas, or require that your application be run with permissions (right-click => Run as Administrator).
I know I don't like random files appearing in my root - I like my files organised.
If it's the user who provides the path, then you should inform them that the file cannot be saved to this location and ask to provide another name.
Usually the shell, GetSaveFileName function, checks whether the new file can be created in the selected directory before returning, see flag OFN_NOTESTFILECREATE in description of OPENFILENAME structure.
Another option is to handle such situation and to show UAC confirmation yourself. But this solution requires much more effort than it's really worth. You can't elevate the current process, so the operation of saving the file to a protected area has to be implemented in another process. At the same time your current process has the data to be saved, so you'll have to implement the communication between the two processes. Read Designing UAC Applications for Windows Vista for more information.

Getting the Windows CE uninstaller to work properly

On some of the devices that I am working on, the \Windows directory is not on permanent storage. That is, once the device is rebooted, whatever was written to \Windows is lost. This is particularly problematic for uninstalling programs since wceload.exe (the Windows CE CAB installer program) generates a .unload file and places it in \Windows. The application can be uninstalled before the device is rebooted, but afterward it can't (the "Remove Programs" tool in the control panel comes back with an error about not being able to open the unload file). So how can I get the .unload file to persist across reboots? Is there any way to control where the uninstaller (I believe it is called unload.exe) looks for the .unload file?
I haven't been able to find any good info on this still. It looks like the path to the unload file is hardcoded so the best I can do is make a backup of the unload file. If the user wishes to uninstall they will have to manually copy the file to the \windows directory and then use the uninstall tool in the control panel. Here is more info:
http://www.generation-nt.com/us/answer/wince5-force-wceload-install-unload-into-nonvolatile-memory-help-87676002.html
You can probably keep the .unload file across reboots by copying it to a persistent directory after installing. This directory may vary per device, e.g. \Hard Disk\ramroot\Windows or \Backup\Windows. It will then automatically be copied to the \Windows on reboot. (Although I am not sure whether such a directory and behavior exist for every device.)
To copy this file you need to execute a copy-statement from a custom setup-dll after the install completes. This codeproject-site has a very comprehensive explanation, with screenshots and code.
Simply re-Install application and then un-install from remove programs in control panel.

Resources