SHCreateItemFromParsingName return FILE_NOT_FOUND when filename specified

gek0n Source

I try get IShellItem for a file to copy it with IFileOperation COM interface from system directory to another directory. I must use exactly IFileOperation COM interface for this purpose.

When I specify full filename - return value from SHCreateItemFromParsingName() was ERROR_FILE_NOT_FOUND, but file present in the directory. When I delete filename from path below and use only folder path - all seems good, return value is S_OK.

//...
CoInitialize(NULL);
//...
WCHAR szSourceDll[MAX_PATH * 2];
wcscpy_s(szSourceDll, MAX_PATH, L"C:\\Windows\\System32\\sysprep\\cryptbase.dll");
r = CoCreateInstance(&CLSID_FileOperation, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER, &IID_IFileOperation, &FileOperation1);
if (r != S_OK) return;
FileOperation1->lpVtbl->SetOperationFlags(FileOperation1, FOF_NOCONFIRMATION | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION);
r = SHCreateItemFromParsingName(szSourceDll, NULL, &IID_IShellItem, &isrc);
//...
CoUninitialize();
//...

Why this code, written in C, not working with filenames. How can I create IShellItem instance for file in system folder to copy it?

P.S.

Windows 7 x64, C, Visual Studio 2015, v140 platform toolset, additional dependencies: Msi.lib;Wuguid.lib;ole32.lib;ntdll.lib

P.P.S

It's properly work with files in user`s directories...

cwinapicommsdn

Answers

answered 8 months ago Anders #1

Assuming your application is compiled as a 32-bit application and running on a 64-bit OS, a file not found error is probably correct because your application is redirected to the 32-bit system directory (%WinDir%\SysWoW64).

In most cases, whenever a 32-bit application attempts to access %windir%\System32, %windir%\lastgood\system32, or %windir%\regedit.exe, the access is redirected to an architecture-specific path.

For more information, see File System Redirector on MSDN.

You could temporarily turn off redirection in your thread but it is not really safe to do this when calling shell functions, only functions in kernel32. If the API you are calling internally uses LoadLibrary and/or COM then the API might fail because it will be unable to load from system32 while redirection is disabled.

You can also access the native system32 directory with the %WinDir%\SysNative backdoor. This only works in 32-bit applications on 64-bit Vista+ so you must do some version detection.

comments powered by Disqus