Continuing from Creating a simple pidl: For the times you care enough to send the very fake: Instead of creating a simple pidl, we'll create a simple shell item.

The idea is the same. We build a file system bind context containing the information about the fake file, and we pass that bind context to the SH­Create­Shell­Item function.

Take that program that creates a simple pidl and make these changes:

HRESULT CreateSimpleShellItemFromPath(
 _In_ const WIN32_FIND_DATAW *pfd,
 _In_ PCWSTR pszPath,
 _In_ REFIID riid, _Outptr_ void **ppv)
{
 *ppv = nullptr;
 CComPtr<IBindCtx> spbc;
 HRESULT hr = CreateFileSysBindCtx(pfd, &spbc);
 if (SUCCEEDED(hr)) {
  hr = SHCreateItemFromParsingName(pszPath, spbc, riid, ppv);
 }
 return hr;
}

void DoStuffWith(_In_ IShellItem2 *psi2)
{
 // Print the file name
 PCWSTR pszName;
 if (SUCCEEDED(psi2->GetDisplayName(
         SIGDN_DESKTOPABSOLUTEPARSING,
         &pszName)) {
  wprintf(L"Path is \"%ls\"\n", pszName);
  CoTaskMemFree(pszName);
 }

 // Print the file size
 ULONGLONG ullSize;
 if (SUCCEEDED(psi2->GetUInt64(PKEY_Size, &ullSize))) {
  wprintf(L"Size is %I64u\n", ullSize);
 }
}

int __cdecl wmain(int argc, PWSTR argv[])
{
 CCoInitialize init;
 if (SUCCEEDED(init)) {
  WIN32_FIND_DATAW fd = {};
  fd.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
  fd.nFileSizeLow = 42;
  CComPtr<IShellItem2> spsi2;
  if (SUCCEEDED(CreateSimpleShellItemFromPath(&fd,
                L"Q:\\Whatever.txt", IID_PPV_ARGS(&spsi2)))) {
   DoStuffWith(spsi2);
  }
 }
 return 0;
}

Instead of creating a simple pidl, we create a simple shell item and then extract the same information from it it as before, just doing it the IShell­Item way.