-1

I'm creating a windows service that copies a file to an external thumb drive using CopyFileW. Everything works as expected, but the problem is that windows copies the file to thumb drive and it shows as a 'File' type and can be neither deleted, copied, moved nor renamed. 'File'
I tried GetLastError and there was no errors, i.e CopyFile returned true.
It does work if the destination file is on the C drive. Here's the code responsible for copying the file :

LPWSTR filename = PathFindFileNameW(file.first.c_str());
LPWSTR mediaFilePath = new WCHAR[1000];
wcscpy_s(mediaFilePath, 255, lpdbv->dbcc_name);
wcscat_s(mediaFilePath, 255, L"\\");
wcscat_s(mediaFilePath, 255, filename);

bool copied = CopyFileW(file.first.c_str(), mediaFilePath, false);
if (!copied) {
    logToFile(L"Couldn't copy file, error " + GetLastError());
}
AnotherOne
  • 854
  • 2
  • 8
  • 19
  • I'm using `std::wstring c_str()` function which returns `char*` not `wchar_t*` and `CopyFileW` requires `LPCWSTR ` – AnotherOne Oct 16 '19 at 09:25
  • @VTT ooooh it actually does, I removed and the problem still persists – AnotherOne Oct 16 '19 at 09:31
  • Does it work if the destination file is somewhere on the C drive rather than on the thumb drive? Does it work if you copy the file yourself using `CreatFile`, `ReadFile`, `WriteFile` etc.? – Jabberwocky Oct 16 '19 at 09:38
  • @Jabberwocky I forgot to mention that, I tried it and it actually does work – AnotherOne Oct 16 '19 at 09:39
  • @MekacherAnis my comment has beeen edited, press F5. You should [edit] your question and mention that. – Jabberwocky Oct 16 '19 at 09:40
  • @MekacherAnis Does it work if you copy the file yourself using `CreatFileW`, `ReadFile`, `WriteFile` etc.instead of using `CopyFileW`? – Jabberwocky Oct 16 '19 at 09:44
  • @Jabberwocky I'll try it – AnotherOne Oct 16 '19 at 09:48
  • This is a bit of a far-fetched idea, but it could be worth dumping out the final file name in hex, and making sure there are no hidden control characters hiding in its path. Invalid characters are notorious for causing problems deleting files in standard Windows interfaces. Also worth checking the file's security/permissions, if you can. – paddy Oct 16 '19 at 10:03
  • @paddy I'm trying `Jabberwocky` iead right now, but in the documentation it says that permissions are copied, which is exactly what I want, I'll try dumping the final filename also – AnotherOne Oct 16 '19 at 10:07
  • @MekacherAnis So it looks like a permission problem. – Jabberwocky Oct 16 '19 at 10:13
  • If you're doing this in the message handler for a [DBT_DEVICEARRIVAL](https://learn.microsoft.com/en-us/windows/win32/devio/dbt-devicearrival) event, consider that there may be something that is not yet completely ready. It could be worth testing that out by building the filename but then deferring the copy by a few seconds (e.g. just fire off a `std::thread` as a quick test - doesn't matter if you leak memory etc while testing theories). – paddy Oct 16 '19 at 10:14
  • @Jabberwocky tried the `CreateFile`, `ReadFile`... Idea and it still didn't work – AnotherOne Oct 16 '19 at 10:16
  • @paddy how can I dump the filename in hex ? – AnotherOne Oct 16 '19 at 10:16
  • @paddy tried delaying the copying with 15 `std::thread`s :P and still didn't work – AnotherOne Oct 16 '19 at 10:33
  • @paddy I dumped the filename and there was 0x00 0x20 after ".png", I think it's a space – AnotherOne Oct 16 '19 at 10:59
  • You are allocating 1000 `WCHAR`s but are telling `wcscpy_s/wcscat_s` that they can only use 255 `WCHAR`s, that is a lot of wasted memory, and 255 is too short anyway (`MAX_PATH` is 260). You should use a `std::wstring` instead of a `WCHAR[]`: `std::wstring mediaFilePath = std::wstring(lpdbv->dbcc_name) + "\\" + std::wstring(filename); CopyFileW(..., mediaFilePath.c_str(), ...);` – Remy Lebeau Oct 16 '19 at 14:54

1 Answers1

1

I finally found the error thanks to the comment of "paddy", it's a problem with the destination filename, after dumping it and viewing it in hex, I found that it was appended with 0x00 0x20 which it is a WCHAR space. after removing that extra character at the end the problem was fixed.

AnotherOne
  • 854
  • 2
  • 8
  • 19
  • `PathFindFileNameW()` doesn't append anything, it simply returns a pointer to the first character of the filename in the provided input string. So the space character had to already exist in the original string. – Remy Lebeau Oct 16 '19 at 14:48
  • @Remy Lebeau you're right, it was already in the string and the problem with 1000 WCHAR was typo, as this was a quick hacky code not a finished code – AnotherOne Oct 16 '19 at 15:44