How to copy a file to the same directory (win32) - winapi

Lets say I have a file called f1.txt in a directory D1.
If I cut paste this file in explorer I get a nice file called f1-(Copy).txt. I think in earlier version I would get f1(2).txt.
Anyway the point is can I do this programmatically given just the file path in Win32. Can I say Something like CopyFileWithCleverDupNamingScheme. I don't want to write my own duplicate naming scheme essentially. And any such api needs to return the new name obviously.
TIA

You can use IFileOperation::CopyItem with SetOperationFlags and FOF_RENAMEONCOLLISION.

Use the CopyFile function from WinAPI. It's self-exlainatory :)
BOOL WINAPI CopyFile(
_In_ LPCTSTR lpExistingFileName,
_In_ LPCTSTR lpNewFileName,
_In_ BOOL bFailIfExists
);
You can just append .new to the old filename?
You will have to check if any files of such already exists, but it's not that hard, just check if the file you want to write already exists, if yes, add some number and keep increasing until a filename is foud which is not used.
For that you can use FindFirstFile in combination with FindNextFile

Related

Shell API to copy all files in a folder?

I am using FreePascal/Lazarus, and I am trying to find the correct ShlObj/ShellApi calls to copy all files from a Device's DCIM Folder (i.e. a Camera) to another folder on the filesystem.
Here is the code to select to select the device:
r:= ShlObj.SHBrowseForFolder(x);
But from, there all I have is r, which is a LPITEMIDLIST variable.
Does anyone know the correct code to copy all files inside the Device's DCIM Folder 'r', to a destination folder (i.e. strDest)?
Note: I must use the ShellApi/ShlObj interface to do the copying
I assume that the PIDL specifies an item that is part of the file system, but I believe that is what you intend since you go on to say "copy all files". In which case, call SHGetPathFromIDList to obtain the file system path from the PIDL, and then call SHFileOperation to copy the files.
If you want to perform copying at the shell level, and not be restricted to files, then it's a little more complex. Probably the simplest will be to use IFileOperation, specifically the CopyItem and CopyItems methods. You'll need to be able to go from a PIDL to an IShellItem which can be done with SHCreateItemFromIDList.

get subfolders without For Each Loop?

Is there any method in vb6 to get the Subfolder name without using For Each Loop?
Most of thread suggests using For Each with FSO, but what if I want to get the subfolder name of specific Folder? e.g. Folder next to C:\Windows ?
I badly need this method to minimize the process time in my program. Simply escaping the loop isn't enough for me.
If you're asking what I think you are (how to list the subfolders of C:\Windows), the answer is no, not without looping.
The reason is that internally the VB FSO uses FindFirstFile, along with the accompanying FindNextFile and FindClose you'll find linked on that page) to iterate the subfolders of a specified folder. The loop is necessary once FindFirstFile has found the first match in order to call FindNextFile to continue retrieving the folders, and FindClose once the last match has been found and the next iteration fails.

WinApi FindFirstFile and the file handle

I got some problem with using FindFirstFile/FindNextFile. As I know it returns a handle but I'm not capable to use it with CreateFileMapping/ReadFile because value of returned handle is different than returned from CreateFile. First question: What's the difference between these two handles and the second: is it possible to convert this handle? My only idea is to get the file name and than use CreateFile.
Regards
What's the difference between these two handles
The first one is search handle. Underneath, there's an iterator reading the directory entry in the file system.
The second one is an iterator reading the file content. The file may even be on another volume than the directory entry you've used to locate it. To learn more about that, google "B-Tree" and then "NTFS"
get the file name and than use CreateFile
Yes, but you need to combine directory + file name. I usually call PathAppend API (CPathT::Append, to be precise) to do that.

lockResource() returns a pointer but to an unknown struct

I'm working with visual studio 2003 on Windows 7.
I'm trying to embed a binary file into a windows console application (c++).
I added into the resource script (.rc file) the following line:
SampleFile RCDATA "c:\\sample.zip"
and also added the following code to access the file:
HRSRC hResource = FindResource(NULL, (LPCSTR)"SampleFile", RT_RCDATA);
LPVOID l = LockResource(hResource);
now, hResource is a valid handle and LockResource also succeeds but the pointer l points to some struct, probably a header, that is followed by the actual data of the zip file I was trying to embed.
I managed to spot that the second DWORD in the said header is the size of the file, and the name of the resource ("SampleFile") also appears in the header, but couldn't manage to find a description of the header or at least the header size.
As Luke said, You're missing a LoadResource() call in the middle.
FindResource() essentially gives you a pointer/handle to the resource header, LoadResource() reads that header and gives you a value that (on win32) points to the data itself, but used to be an HGlobal that could be moved in memory. You would then lock this location and get a pointer using LockResource().
The usage stays the same on Win32 though.
From MSDN
Do not try to lock a resource by using the handle returned by the FindResource or FindResourceEx function. Such a handle points to random data.
The resource header is described in MSDN as the fictional RESOURCEHEADER structure.
This reply is largely taken from Raymond Chen's article on 16-bit resource management
You have an Api function to get size of resource SizeofResource.
The pointer points to the beginning of the file added as resource (in your case "c:\sample.zip).
If you want you can pass that pointer to a uncompress library or simply write to disk.
thanks for the help.
Actually I did have LoadResource in my code, which got lost in the copy paste to the site.
However, that is related to the problem in my code.
The code looked like this: (Psuedo code this time)
HANDLE hFindHandle = FindResource(...);
LoadResource(hFindHandle and Module Handle);
and then
LPVOID l = LockResource(hFindHandle);
I didn't use the returned value from the LoadResource but kept using the one from the FindResource, so even though I did call LoadResource, I didn't get the correct pointer from LockResource.

WinAPI function which replaces file but preserves file information

I remember there was a WinAPI function which copied the "date modified" property of the previous file which was replaced with it or something like that? Perhaps anyone can tell me about it?
The problem occured when you used that function very frequently.
This is ReplaceFile (Windows 2000 and up):
The ReplaceFile function combines
several steps within a single
function. An application can call
ReplaceFile instead of calling
separate functions to save the data to
a new file, rename the original file
using a temporary name, rename the new
file to have the same name as the
original file, and delete the original
file. Another advantage is that
ReplaceFile not only copies the new
file data, but also preserves the
following attributes of the original
file:
Creation time
Short file name
Object identifier
DACLs
Encryption
Compression
Named streams not already
in the replacement file
Not too clear exactly what you want, but it seems your after SetFileTime to edit and GetFileTime to copy, combining the two you can do exactly as 'described/wanted'

Resources